Extract implementations of Contacts to separate files; correct package name

This commit is contained in:
Him188 2020-03-24 15:41:26 +08:00
parent 94e40e2e6a
commit 83793d3f7e
7 changed files with 444 additions and 385 deletions

View File

@ -28,6 +28,8 @@ import net.mamoe.mirai.data.*
import net.mamoe.mirai.event.broadcast
import net.mamoe.mirai.event.events.MessageRecallEvent
import net.mamoe.mirai.message.data.*
import net.mamoe.mirai.qqandroid.contact.MemberInfoImpl
import net.mamoe.mirai.qqandroid.contact.QQImpl
import net.mamoe.mirai.qqandroid.message.OnlineFriendImageImpl
import net.mamoe.mirai.qqandroid.message.OnlineGroupImageImpl
import net.mamoe.mirai.qqandroid.network.QQAndroidBotNetworkHandler

View File

@ -9,383 +9,34 @@
@file: Suppress("INAPPLICABLE_JVM_NAME")
package net.mamoe.mirai.qqandroid
package net.mamoe.mirai.qqandroid.contact
import kotlinx.coroutines.launch
import kotlinx.coroutines.withTimeoutOrNull
import kotlinx.io.core.Closeable
import net.mamoe.mirai.LowLevelAPI
import net.mamoe.mirai.contact.*
import net.mamoe.mirai.data.*
import net.mamoe.mirai.data.GroupInfo
import net.mamoe.mirai.data.MemberInfo
import net.mamoe.mirai.event.broadcast
import net.mamoe.mirai.event.events.*
import net.mamoe.mirai.event.events.MessageSendEvent.FriendMessageSendEvent
import net.mamoe.mirai.event.events.MessageSendEvent.GroupMessageSendEvent
import net.mamoe.mirai.message.MessageReceipt
import net.mamoe.mirai.message.data.*
import net.mamoe.mirai.message.data.Message
import net.mamoe.mirai.message.data.OfflineGroupImage
import net.mamoe.mirai.message.data.asMessageChain
import net.mamoe.mirai.qqandroid.QQAndroidBot
import net.mamoe.mirai.qqandroid.message.MessageSourceFromSendGroup
import net.mamoe.mirai.qqandroid.network.highway.HighwayHelper
import net.mamoe.mirai.qqandroid.network.highway.postImage
import net.mamoe.mirai.qqandroid.network.protocol.data.jce.StTroopMemberInfo
import net.mamoe.mirai.qqandroid.network.protocol.data.proto.Cmd0x352
import net.mamoe.mirai.qqandroid.network.protocol.packet.chat.TroopManagement
import net.mamoe.mirai.qqandroid.network.protocol.packet.chat.image.ImgStore
import net.mamoe.mirai.qqandroid.network.protocol.packet.chat.image.LongConn
import net.mamoe.mirai.qqandroid.network.protocol.packet.chat.receive.MessageSvc
import net.mamoe.mirai.qqandroid.utils.toIpV4AddressString
import net.mamoe.mirai.utils.*
import net.mamoe.mirai.utils.io.toUHexString
import kotlin.contracts.ExperimentalContracts
import kotlin.contracts.contract
import kotlin.coroutines.CoroutineContext
import kotlin.jvm.JvmSynthetic
import net.mamoe.mirai.qqandroid.network.protocol.data.jce.FriendInfo as JceFriendInfo
internal inline class FriendInfoImpl(
private val jceFriendInfo: JceFriendInfo
) : FriendInfo {
override val nick: String get() = jceFriendInfo.nick ?: ""
override val uin: Long get() = jceFriendInfo.friendUin
}
internal class QQImpl(
bot: QQAndroidBot,
override val coroutineContext: CoroutineContext,
override val id: Long,
private val friendInfo: FriendInfo
) : QQ() {
override val bot: QQAndroidBot by bot.unsafeWeakRef()
override val nick: String
get() = friendInfo.nick
@JvmSynthetic
@Suppress("DuplicatedCode")
override suspend fun sendMessage(message: Message): MessageReceipt<out QQ> {
val event = FriendMessageSendEvent(this, message.asMessageChain()).broadcast()
if (event.isCancelled) {
throw EventCancelledException("cancelled by FriendMessageSendEvent")
}
lateinit var source: MessageSource
bot.network.run {
check(
MessageSvc.PbSendMsg.ToFriend(
bot.client,
id,
event.message
) {
source = it
}.sendAndExpect<MessageSvc.PbSendMsg.Response>() is MessageSvc.PbSendMsg.Response.SUCCESS
) { "send message failed" }
}
return MessageReceipt(source, this, null)
}
@JvmSynthetic
@OptIn(MiraiInternalAPI::class)
override suspend fun uploadImage(image: ExternalImage): OfflineFriendImage = try {
if (BeforeImageUploadEvent(this, image).broadcast().isCancelled) {
throw EventCancelledException("cancelled by BeforeImageUploadEvent.ToGroup")
}
bot.network.run {
val response = LongConn.OffPicUp(
bot.client, Cmd0x352.TryUpImgReq(
srcUin = bot.uin.toInt(),
dstUin = id.toInt(),
fileId = 0,
fileMd5 = image.md5,
fileSize = image.inputSize.toInt(),
fileName = image.md5.toUHexString("") + "." + image.format,
imgOriginal = 1,
imgWidth = image.width,
imgHeight = image.height,
imgType = image.imageType
)
).sendAndExpect<LongConn.OffPicUp.Response>()
@Suppress("UNCHECKED_CAST") // bug
return when (response) {
is LongConn.OffPicUp.Response.FileExists -> OfflineFriendImage(
filepath = response.resourceId,
md5 = response.imageInfo.fileMd5,
fileLength = response.imageInfo.fileSize.toInt(),
height = response.imageInfo.fileHeight,
width = response.imageInfo.fileWidth,
resourceId = response.resourceId
).also {
ImageUploadEvent.Succeed(this@QQImpl, image, it).broadcast()
}
is LongConn.OffPicUp.Response.RequireUpload -> {
MiraiPlatformUtils.Http.postImage(
"0x6ff0070",
bot.uin,
null,
imageInput = image.input,
inputSize = image.inputSize,
uKeyHex = response.uKey.toUHexString("")
)
//HighwayHelper.uploadImage(
// client = bot.client,
// serverIp = response.serverIp[0].toIpV4AddressString(),
// serverPort = response.serverPort[0],
// imageInput = image.input,
// inputSize = image.inputSize.toInt(),
// fileMd5 = image.md5,
// uKey = response.uKey,
// commandId = 1
//)
// 为什么不能 ??
return OfflineFriendImage(
filepath = response.resourceId,
md5 = image.md5,
fileLength = image.inputSize.toInt(),
height = image.height,
width = image.width,
resourceId = response.resourceId
).also {
ImageUploadEvent.Succeed(this@QQImpl, image, it).broadcast()
}
}
is LongConn.OffPicUp.Response.Failed -> {
ImageUploadEvent.Failed(this@QQImpl, image, -1, response.message).broadcast()
error(response.message)
}
}
}
} finally {
(image.input as? Closeable)?.close()
(image.input as? Closeable)?.close()
}
override fun hashCode(): Int {
var result = bot.hashCode()
result = 31 * result + id.hashCode()
return result
}
override fun equals(other: Any?): Boolean {
@Suppress("DuplicatedCode")
if (this === other) return true
if (other !is Contact) return false
if (this::class != other::class) return false
return this.id == other.id && this.bot == other.bot
}
@MiraiExperimentalAPI
override suspend fun queryProfile(): Profile {
TODO("not implemented")
}
@MiraiExperimentalAPI
override suspend fun queryPreviousNameList(): PreviousNameList {
TODO("not implemented")
}
@MiraiExperimentalAPI
override suspend fun queryRemark(): FriendNameRemark {
TODO("not implemented")
}
override fun toString(): String = "QQ($id)"
}
@Suppress("MemberVisibilityCanBePrivate")
internal class MemberImpl(
val qq: QQImpl, // 不要 WeakRef
group: GroupImpl,
override val coroutineContext: CoroutineContext,
memberInfo: MemberInfo
) : Member() {
override val group: GroupImpl by group.unsafeWeakRef()
// region QQ delegate
override val id: Long = qq.id
override val nick: String = qq.nick
@MiraiExperimentalAPI
override suspend fun queryProfile(): Profile = qq.queryProfile()
@MiraiExperimentalAPI
override suspend fun queryPreviousNameList(): PreviousNameList = qq.queryPreviousNameList()
@MiraiExperimentalAPI
override suspend fun queryRemark(): FriendNameRemark = qq.queryRemark()
@JvmSynthetic
@Suppress("DuplicatedCode")
override suspend fun sendMessage(message: Message): MessageReceipt<Member> {
val event = FriendMessageSendEvent(this, message.asMessageChain()).broadcast()
if (event.isCancelled) {
throw EventCancelledException("cancelled by FriendMessageSendEvent")
}
lateinit var source: MessageSource
bot.network.run {
check(
MessageSvc.PbSendMsg.ToFriend(
bot.client,
id,
event.message
) {
source = it
}.sendAndExpect<MessageSvc.PbSendMsg.Response>() is MessageSvc.PbSendMsg.Response.SUCCESS
) { "send message failed" }
}
return MessageReceipt(source, this, null)
}
@JvmSynthetic
override suspend fun uploadImage(image: ExternalImage): OfflineFriendImage = qq.uploadImage(image)
// endregion
override var permission: MemberPermission = memberInfo.permission
@Suppress("PropertyName")
internal var _nameCard: String = memberInfo.nameCard
@Suppress("PropertyName")
internal var _specialTitle: String = memberInfo.specialTitle
@Suppress("PropertyName")
var _muteTimestamp: Int = memberInfo.muteTimestamp
override val muteTimeRemaining: Int =
if (_muteTimestamp == 0 || _muteTimestamp == 0xFFFFFFFF.toInt()) {
0
} else {
_muteTimestamp - currentTimeSeconds.toInt() - bot.client.timeDifference.toInt()
}
override var nameCard: String
get() = _nameCard
set(newValue) {
group.checkBotPermissionOperator()
if (_nameCard != newValue) {
val oldValue = _nameCard
_nameCard = newValue
launch {
bot.network.run {
TroopManagement.EditGroupNametag(
bot.client,
this@MemberImpl,
newValue
).sendWithoutExpect()
}
MemberCardChangeEvent(oldValue, newValue, this@MemberImpl, null).broadcast()
}
}
}
override var specialTitle: String
get() = _specialTitle
set(newValue) {
group.checkBotPermission(MemberPermission.OWNER)
if (_specialTitle != newValue) {
val oldValue = _specialTitle
_specialTitle = newValue
launch {
bot.network.run {
TroopManagement.EditSpecialTitle(
bot.client,
this@MemberImpl,
newValue
).sendWithoutExpect()
}
MemberSpecialTitleChangeEvent(oldValue, newValue, this@MemberImpl, null).broadcast()
}
}
}
override val bot: QQAndroidBot get() = qq.bot
@JvmSynthetic
override suspend fun mute(durationSeconds: Int) {
if (group.botPermission != MemberPermission.OWNER && (!group.botPermission.isOperator() || this.isOperator())) {
throw PermissionDeniedException()
}
bot.network.run {
TroopManagement.Mute(
client = bot.client,
groupCode = group.id,
memberUin = this@MemberImpl.id,
timeInSecond = durationSeconds
).sendAndExpect<TroopManagement.Mute.Response>()
}
@Suppress("RemoveRedundantQualifierName") // or unresolved reference
net.mamoe.mirai.event.events.MemberMuteEvent(this@MemberImpl, durationSeconds, null).broadcast()
}
@JvmSynthetic
override suspend fun unmute() {
if (group.botPermission != MemberPermission.OWNER && (!group.botPermission.isOperator() || this.isOperator())) {
throw PermissionDeniedException()
}
bot.network.run {
TroopManagement.Mute(
client = bot.client,
groupCode = group.id,
memberUin = this@MemberImpl.id,
timeInSecond = 0
).sendAndExpect<TroopManagement.Mute.Response>()
}
@Suppress("RemoveRedundantQualifierName") // or unresolved reference
net.mamoe.mirai.event.events.MemberUnmuteEvent(this@MemberImpl, null).broadcast()
}
@JvmSynthetic
override suspend fun kick(message: String) {
if (group.botPermission != MemberPermission.OWNER && (!group.botPermission.isOperator() || this.isOperator())) {
throw PermissionDeniedException()
}
bot.network.run {
TroopManagement.Kick(
client = bot.client,
member = this@MemberImpl,
message = message
).sendAndExpect<TroopManagement.Kick.Response>().success.also {
MemberLeaveEvent.Kick(this@MemberImpl, null).broadcast()
}
}
}
override fun hashCode(): Int {
var result = bot.hashCode()
result = 31 * result + id.hashCode()
return result
}
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other !is Contact) return false
if (this::class != other::class) return false
return this.id == other.id && this.bot == other.bot
}
override fun toString(): String {
return "Member($id)"
}
}
internal class MemberInfoImpl(
jceInfo: StTroopMemberInfo,
groupOwnerId: Long
) : MemberInfo {
override val uin: Long = jceInfo.memberUin
override val nameCard: String = jceInfo.sName ?: ""
override val nick: String = jceInfo.nick
override val permission: MemberPermission = when {
jceInfo.memberUin == groupOwnerId -> MemberPermission.OWNER
jceInfo.dwFlag == 1L -> MemberPermission.ADMINISTRATOR
else -> MemberPermission.MEMBER
}
override val specialTitle: String = jceInfo.sSpecialTitle ?: ""
override val muteTimestamp: Int = jceInfo.dwShutupTimestap?.toInt() ?: 0
}
@OptIn(ExperimentalContracts::class)
internal fun GroupImpl.Companion.checkIsInstance(expression: Boolean) {

View File

@ -0,0 +1,229 @@
/*
* Copyright 2020 Mamoe Technologies and contributors.
*
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
*
* https://github.com/mamoe/mirai/blob/master/LICENSE
*/
package net.mamoe.mirai.qqandroid.contact
import kotlinx.coroutines.launch
import net.mamoe.mirai.contact.*
import net.mamoe.mirai.data.FriendNameRemark
import net.mamoe.mirai.data.MemberInfo
import net.mamoe.mirai.data.PreviousNameList
import net.mamoe.mirai.data.Profile
import net.mamoe.mirai.event.broadcast
import net.mamoe.mirai.event.events.*
import net.mamoe.mirai.message.MessageReceipt
import net.mamoe.mirai.message.data.Message
import net.mamoe.mirai.message.data.MessageSource
import net.mamoe.mirai.message.data.OfflineFriendImage
import net.mamoe.mirai.message.data.asMessageChain
import net.mamoe.mirai.qqandroid.QQAndroidBot
import net.mamoe.mirai.qqandroid.network.protocol.data.jce.StTroopMemberInfo
import net.mamoe.mirai.qqandroid.network.protocol.packet.chat.TroopManagement
import net.mamoe.mirai.qqandroid.network.protocol.packet.chat.receive.MessageSvc
import net.mamoe.mirai.utils.*
import kotlin.coroutines.CoroutineContext
import kotlin.jvm.JvmSynthetic
@Suppress("MemberVisibilityCanBePrivate")
internal class MemberImpl(
val qq: QQImpl, // 不要 WeakRef
group: GroupImpl,
override val coroutineContext: CoroutineContext,
memberInfo: MemberInfo
) : Member() {
override val group: GroupImpl by group.unsafeWeakRef()
// region QQ delegate
override val id: Long = qq.id
override val nick: String = qq.nick
@MiraiExperimentalAPI
override suspend fun queryProfile(): Profile = qq.queryProfile()
@MiraiExperimentalAPI
override suspend fun queryPreviousNameList(): PreviousNameList = qq.queryPreviousNameList()
@MiraiExperimentalAPI
override suspend fun queryRemark(): FriendNameRemark = qq.queryRemark()
@JvmSynthetic
@Suppress("DuplicatedCode")
override suspend fun sendMessage(message: Message): MessageReceipt<Member> {
val event = MessageSendEvent.FriendMessageSendEvent(this, message.asMessageChain()).broadcast()
if (event.isCancelled) {
throw EventCancelledException("cancelled by FriendMessageSendEvent")
}
lateinit var source: MessageSource
bot.network.run {
check(
MessageSvc.PbSendMsg.ToFriend(
bot.client,
id,
event.message
) {
source = it
}.sendAndExpect<MessageSvc.PbSendMsg.Response>() is MessageSvc.PbSendMsg.Response.SUCCESS
) { "send message failed" }
}
return MessageReceipt(source, this, null)
}
@JvmSynthetic
override suspend fun uploadImage(image: ExternalImage): OfflineFriendImage = qq.uploadImage(image)
// endregion
override var permission: MemberPermission = memberInfo.permission
@Suppress("PropertyName")
internal var _nameCard: String = memberInfo.nameCard
@Suppress("PropertyName")
internal var _specialTitle: String = memberInfo.specialTitle
@Suppress("PropertyName")
var _muteTimestamp: Int = memberInfo.muteTimestamp
override val muteTimeRemaining: Int =
if (_muteTimestamp == 0 || _muteTimestamp == 0xFFFFFFFF.toInt()) {
0
} else {
_muteTimestamp - currentTimeSeconds.toInt() - bot.client.timeDifference.toInt()
}
override var nameCard: String
get() = _nameCard
set(newValue) {
group.checkBotPermissionOperator()
if (_nameCard != newValue) {
val oldValue = _nameCard
_nameCard = newValue
launch {
bot.network.run {
TroopManagement.EditGroupNametag(
bot.client,
this@MemberImpl,
newValue
).sendWithoutExpect()
}
MemberCardChangeEvent(oldValue, newValue, this@MemberImpl, null).broadcast()
}
}
}
override var specialTitle: String
get() = _specialTitle
set(newValue) {
group.checkBotPermission(MemberPermission.OWNER)
if (_specialTitle != newValue) {
val oldValue = _specialTitle
_specialTitle = newValue
launch {
bot.network.run {
TroopManagement.EditSpecialTitle(
bot.client,
this@MemberImpl,
newValue
).sendWithoutExpect()
}
MemberSpecialTitleChangeEvent(oldValue, newValue, this@MemberImpl, null).broadcast()
}
}
}
override val bot: QQAndroidBot get() = qq.bot
@JvmSynthetic
override suspend fun mute(durationSeconds: Int) {
if (group.botPermission != MemberPermission.OWNER && (!group.botPermission.isOperator() || this.isOperator())) {
throw PermissionDeniedException()
}
bot.network.run {
TroopManagement.Mute(
client = bot.client,
groupCode = group.id,
memberUin = this@MemberImpl.id,
timeInSecond = durationSeconds
).sendAndExpect<TroopManagement.Mute.Response>()
}
@Suppress("RemoveRedundantQualifierName") // or unresolved reference
net.mamoe.mirai.event.events.MemberMuteEvent(this@MemberImpl, durationSeconds, null).broadcast()
}
@JvmSynthetic
override suspend fun unmute() {
if (group.botPermission != MemberPermission.OWNER && (!group.botPermission.isOperator() || this.isOperator())) {
throw PermissionDeniedException()
}
bot.network.run {
TroopManagement.Mute(
client = bot.client,
groupCode = group.id,
memberUin = this@MemberImpl.id,
timeInSecond = 0
).sendAndExpect<TroopManagement.Mute.Response>()
}
@Suppress("RemoveRedundantQualifierName") // or unresolved reference
net.mamoe.mirai.event.events.MemberUnmuteEvent(this@MemberImpl, null).broadcast()
}
@JvmSynthetic
override suspend fun kick(message: String) {
if (group.botPermission != MemberPermission.OWNER && (!group.botPermission.isOperator() || this.isOperator())) {
throw PermissionDeniedException()
}
bot.network.run {
TroopManagement.Kick(
client = bot.client,
member = this@MemberImpl,
message = message
).sendAndExpect<TroopManagement.Kick.Response>().success.also {
MemberLeaveEvent.Kick(this@MemberImpl, null).broadcast()
}
}
}
override fun hashCode(): Int {
var result = bot.hashCode()
result = 31 * result + id.hashCode()
return result
}
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other !is Contact) return false
if (this::class != other::class) return false
return this.id == other.id && this.bot == other.bot
}
override fun toString(): String {
return "Member($id)"
}
}
internal class MemberInfoImpl(
jceInfo: StTroopMemberInfo,
groupOwnerId: Long
) : MemberInfo {
override val uin: Long = jceInfo.memberUin
override val nameCard: String = jceInfo.sName ?: ""
override val nick: String = jceInfo.nick
override val permission: MemberPermission = when {
jceInfo.memberUin == groupOwnerId -> MemberPermission.OWNER
jceInfo.dwFlag == 1L -> MemberPermission.ADMINISTRATOR
else -> MemberPermission.MEMBER
}
override val specialTitle: String = jceInfo.sSpecialTitle ?: ""
override val muteTimestamp: Int = jceInfo.dwShutupTimestap?.toInt() ?: 0
}

View File

@ -0,0 +1,177 @@
package net.mamoe.mirai.qqandroid.contact
import kotlinx.io.core.Closeable
import net.mamoe.mirai.contact.Contact
import net.mamoe.mirai.contact.QQ
import net.mamoe.mirai.data.FriendInfo
import net.mamoe.mirai.data.FriendNameRemark
import net.mamoe.mirai.data.PreviousNameList
import net.mamoe.mirai.data.Profile
import net.mamoe.mirai.event.broadcast
import net.mamoe.mirai.event.events.BeforeImageUploadEvent
import net.mamoe.mirai.event.events.EventCancelledException
import net.mamoe.mirai.event.events.ImageUploadEvent
import net.mamoe.mirai.event.events.MessageSendEvent
import net.mamoe.mirai.message.MessageReceipt
import net.mamoe.mirai.message.data.Message
import net.mamoe.mirai.message.data.MessageSource
import net.mamoe.mirai.message.data.OfflineFriendImage
import net.mamoe.mirai.message.data.asMessageChain
import net.mamoe.mirai.qqandroid.QQAndroidBot
import net.mamoe.mirai.qqandroid.network.highway.postImage
import net.mamoe.mirai.qqandroid.network.protocol.data.proto.Cmd0x352
import net.mamoe.mirai.qqandroid.network.protocol.packet.chat.image.LongConn
import net.mamoe.mirai.qqandroid.network.protocol.packet.chat.receive.MessageSvc
import net.mamoe.mirai.utils.*
import net.mamoe.mirai.utils.io.toUHexString
import kotlin.coroutines.CoroutineContext
import kotlin.jvm.JvmSynthetic
internal inline class FriendInfoImpl(
private val jceFriendInfo: net.mamoe.mirai.qqandroid.network.protocol.data.jce.FriendInfo
) : FriendInfo {
override val nick: String get() = jceFriendInfo.nick ?: ""
override val uin: Long get() = jceFriendInfo.friendUin
}
internal class QQImpl(
bot: QQAndroidBot,
override val coroutineContext: CoroutineContext,
override val id: Long,
private val friendInfo: FriendInfo
) : QQ() {
override val bot: QQAndroidBot by bot.unsafeWeakRef()
override val nick: String
get() = friendInfo.nick
@JvmSynthetic
@Suppress("DuplicatedCode")
override suspend fun sendMessage(message: Message): MessageReceipt<out QQ> {
val event = MessageSendEvent.FriendMessageSendEvent(this, message.asMessageChain()).broadcast()
if (event.isCancelled) {
throw EventCancelledException("cancelled by FriendMessageSendEvent")
}
lateinit var source: MessageSource
bot.network.run {
check(
MessageSvc.PbSendMsg.ToFriend(
bot.client,
id,
event.message
) {
source = it
}
.sendAndExpect<MessageSvc.PbSendMsg.Response>() is MessageSvc.PbSendMsg.Response.SUCCESS
) { "send message failed" }
}
return MessageReceipt(source, this, null)
}
@JvmSynthetic
@OptIn(MiraiInternalAPI::class)
override suspend fun uploadImage(image: ExternalImage): OfflineFriendImage = try {
if (BeforeImageUploadEvent(this, image).broadcast().isCancelled) {
throw EventCancelledException("cancelled by BeforeImageUploadEvent.ToGroup")
}
bot.network.run {
val response = LongConn.OffPicUp(
bot.client, Cmd0x352.TryUpImgReq(
srcUin = bot.uin.toInt(),
dstUin = id.toInt(),
fileId = 0,
fileMd5 = image.md5,
fileSize = image.inputSize.toInt(),
fileName = image.md5.toUHexString("") + "." + image.format,
imgOriginal = 1,
imgWidth = image.width,
imgHeight = image.height,
imgType = image.imageType
)
).sendAndExpect<LongConn.OffPicUp.Response>()
@Suppress("UNCHECKED_CAST") // bug
return when (response) {
is LongConn.OffPicUp.Response.FileExists -> OfflineFriendImage(
filepath = response.resourceId,
md5 = response.imageInfo.fileMd5,
fileLength = response.imageInfo.fileSize.toInt(),
height = response.imageInfo.fileHeight,
width = response.imageInfo.fileWidth,
resourceId = response.resourceId
).also {
ImageUploadEvent.Succeed(this@QQImpl, image, it).broadcast()
}
is LongConn.OffPicUp.Response.RequireUpload -> {
MiraiPlatformUtils.Http.postImage(
"0x6ff0070",
bot.uin,
null,
imageInput = image.input,
inputSize = image.inputSize,
uKeyHex = response.uKey.toUHexString("")
)
//HighwayHelper.uploadImage(
// client = bot.client,
// serverIp = response.serverIp[0].toIpV4AddressString(),
// serverPort = response.serverPort[0],
// imageInput = image.input,
// inputSize = image.inputSize.toInt(),
// fileMd5 = image.md5,
// uKey = response.uKey,
// commandId = 1
//)
// 为什么不能 ??
return OfflineFriendImage(
filepath = response.resourceId,
md5 = image.md5,
fileLength = image.inputSize.toInt(),
height = image.height,
width = image.width,
resourceId = response.resourceId
).also {
ImageUploadEvent.Succeed(this@QQImpl, image, it).broadcast()
}
}
is LongConn.OffPicUp.Response.Failed -> {
ImageUploadEvent.Failed(this@QQImpl, image, -1, response.message).broadcast()
error(response.message)
}
}
}
} finally {
(image.input as? Closeable)?.close()
(image.input as? Closeable)?.close()
}
override fun hashCode(): Int {
var result = bot.hashCode()
result = 31 * result + id.hashCode()
return result
}
override fun equals(other: Any?): Boolean {
@Suppress("DuplicatedCode")
if (this === other) return true
if (other !is Contact) return false
if (this::class != other::class) return false
return this.id == other.id && this.bot == other.bot
}
@MiraiExperimentalAPI
override suspend fun queryProfile(): Profile {
TODO("not implemented")
}
@MiraiExperimentalAPI
override suspend fun queryPreviousNameList(): PreviousNameList {
TODO("not implemented")
}
@MiraiExperimentalAPI
override suspend fun queryRemark(): FriendNameRemark {
TODO("not implemented")
}
override fun toString(): String = "QQ($id)"
}

View File

@ -25,10 +25,10 @@ import net.mamoe.mirai.event.events.BotOfflineEvent
import net.mamoe.mirai.event.events.BotOnlineEvent
import net.mamoe.mirai.network.BotNetworkHandler
import net.mamoe.mirai.network.WrongPasswordException
import net.mamoe.mirai.qqandroid.FriendInfoImpl
import net.mamoe.mirai.qqandroid.GroupImpl
import net.mamoe.mirai.qqandroid.QQAndroidBot
import net.mamoe.mirai.qqandroid.QQImpl
import net.mamoe.mirai.qqandroid.contact.FriendInfoImpl
import net.mamoe.mirai.qqandroid.contact.GroupImpl
import net.mamoe.mirai.qqandroid.contact.QQImpl
import net.mamoe.mirai.qqandroid.event.PacketReceivedEvent
import net.mamoe.mirai.qqandroid.network.protocol.data.proto.MsgSvc
import net.mamoe.mirai.qqandroid.network.protocol.packet.*
@ -264,32 +264,32 @@ internal class QQAndroidBotNetworkHandler(bot: QQAndroidBot) : BotNetworkHandler
bot.groups.delegate.addLast(
@Suppress("DuplicatedCode")
(GroupImpl(
bot = bot,
coroutineContext = bot.coroutineContext,
id = troopNum.groupCode,
groupInfo = bot._lowLevelQueryGroupInfo(troopNum.groupCode).apply {
this as GroupInfoImpl
bot = bot,
coroutineContext = bot.coroutineContext,
id = troopNum.groupCode,
groupInfo = bot._lowLevelQueryGroupInfo(troopNum.groupCode).apply {
this as GroupInfoImpl
if (this.delegate.groupName == null) {
this.delegate.groupName = troopNum.groupName
}
if (this.delegate.groupName == null) {
this.delegate.groupName = troopNum.groupName
}
if (this.delegate.groupMemo == null) {
this.delegate.groupMemo = troopNum.groupMemo
}
if (this.delegate.groupMemo == null) {
this.delegate.groupMemo = troopNum.groupMemo
}
if (this.delegate.groupUin == null) {
this.delegate.groupUin = troopNum.groupUin
}
if (this.delegate.groupUin == null) {
this.delegate.groupUin = troopNum.groupUin
}
this.delegate.groupCode = troopNum.groupCode
},
members = bot._lowLevelQueryGroupMemberList(
troopNum.groupUin,
troopNum.groupCode,
troopNum.dwGroupOwnerUin
)
))
this.delegate.groupCode = troopNum.groupCode
},
members = bot._lowLevelQueryGroupMemberList(
troopNum.groupUin,
troopNum.groupCode,
troopNum.dwGroupOwnerUin
)
))
)
}?.let {
logger.error { "${troopNum.groupCode}的列表拉取失败, 一段时间后将会重试" }

View File

@ -24,7 +24,7 @@ import net.mamoe.mirai.event.events.MemberJoinEvent
import net.mamoe.mirai.getFriendOrNull
import net.mamoe.mirai.message.FriendMessage
import net.mamoe.mirai.message.data.MessageChain
import net.mamoe.mirai.qqandroid.GroupImpl
import net.mamoe.mirai.qqandroid.contact.GroupImpl
import net.mamoe.mirai.qqandroid.QQAndroidBot
import net.mamoe.mirai.qqandroid.io.serialization.decodeUniPacket
import net.mamoe.mirai.qqandroid.io.serialization.readProtoBuf

View File

@ -19,10 +19,10 @@ import net.mamoe.mirai.data.Packet
import net.mamoe.mirai.event.Event
import net.mamoe.mirai.event.events.*
import net.mamoe.mirai.message.GroupMessage
import net.mamoe.mirai.qqandroid.GroupImpl
import net.mamoe.mirai.qqandroid.MemberImpl
import net.mamoe.mirai.qqandroid.contact.GroupImpl
import net.mamoe.mirai.qqandroid.contact.MemberImpl
import net.mamoe.mirai.qqandroid.QQAndroidBot
import net.mamoe.mirai.qqandroid.checkIsInstance
import net.mamoe.mirai.qqandroid.contact.checkIsInstance
import net.mamoe.mirai.qqandroid.io.serialization.decodeUniPacket
import net.mamoe.mirai.qqandroid.io.serialization.readProtoBuf
import net.mamoe.mirai.qqandroid.message.toMessageChain