Commit 83793d3f authored by Him188's avatar Him188

Extract implementations of `Contact`s to separate files; correct package name

parent 94e40e2e
...@@ -28,6 +28,8 @@ import net.mamoe.mirai.data.* ...@@ -28,6 +28,8 @@ import net.mamoe.mirai.data.*
import net.mamoe.mirai.event.broadcast import net.mamoe.mirai.event.broadcast
import net.mamoe.mirai.event.events.MessageRecallEvent import net.mamoe.mirai.event.events.MessageRecallEvent
import net.mamoe.mirai.message.data.* 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.OnlineFriendImageImpl
import net.mamoe.mirai.qqandroid.message.OnlineGroupImageImpl import net.mamoe.mirai.qqandroid.message.OnlineGroupImageImpl
import net.mamoe.mirai.qqandroid.network.QQAndroidBotNetworkHandler import net.mamoe.mirai.qqandroid.network.QQAndroidBotNetworkHandler
......
...@@ -9,383 +9,34 @@ ...@@ -9,383 +9,34 @@
@file: Suppress("INAPPLICABLE_JVM_NAME") @file: Suppress("INAPPLICABLE_JVM_NAME")
package net.mamoe.mirai.qqandroid package net.mamoe.mirai.qqandroid.contact
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withTimeoutOrNull import kotlinx.coroutines.withTimeoutOrNull
import kotlinx.io.core.Closeable import kotlinx.io.core.Closeable
import net.mamoe.mirai.LowLevelAPI import net.mamoe.mirai.LowLevelAPI
import net.mamoe.mirai.contact.* 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.broadcast
import net.mamoe.mirai.event.events.* 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.event.events.MessageSendEvent.GroupMessageSendEvent
import net.mamoe.mirai.message.MessageReceipt 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.message.MessageSourceFromSendGroup
import net.mamoe.mirai.qqandroid.network.highway.HighwayHelper 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.TroopManagement
import net.mamoe.mirai.qqandroid.network.protocol.packet.chat.image.ImgStore 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.network.protocol.packet.chat.receive.MessageSvc
import net.mamoe.mirai.qqandroid.utils.toIpV4AddressString import net.mamoe.mirai.qqandroid.utils.toIpV4AddressString
import net.mamoe.mirai.utils.* import net.mamoe.mirai.utils.*
import net.mamoe.mirai.utils.io.toUHexString
import kotlin.contracts.ExperimentalContracts import kotlin.contracts.ExperimentalContracts
import kotlin.contracts.contract import kotlin.contracts.contract
import kotlin.coroutines.CoroutineContext import kotlin.coroutines.CoroutineContext
import kotlin.jvm.JvmSynthetic 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) @OptIn(ExperimentalContracts::class)
internal fun GroupImpl.Companion.checkIsInstance(expression: Boolean) { internal fun GroupImpl.Companion.checkIsInstance(expression: Boolean) {
......
/*
* 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
}
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)"
}
\ No newline at end of file
...@@ -25,10 +25,10 @@ import net.mamoe.mirai.event.events.BotOfflineEvent ...@@ -25,10 +25,10 @@ import net.mamoe.mirai.event.events.BotOfflineEvent
import net.mamoe.mirai.event.events.BotOnlineEvent import net.mamoe.mirai.event.events.BotOnlineEvent
import net.mamoe.mirai.network.BotNetworkHandler import net.mamoe.mirai.network.BotNetworkHandler
import net.mamoe.mirai.network.WrongPasswordException 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.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.event.PacketReceivedEvent
import net.mamoe.mirai.qqandroid.network.protocol.data.proto.MsgSvc import net.mamoe.mirai.qqandroid.network.protocol.data.proto.MsgSvc
import net.mamoe.mirai.qqandroid.network.protocol.packet.* import net.mamoe.mirai.qqandroid.network.protocol.packet.*
...@@ -264,32 +264,32 @@ internal class QQAndroidBotNetworkHandler(bot: QQAndroidBot) : BotNetworkHandler ...@@ -264,32 +264,32 @@ internal class QQAndroidBotNetworkHandler(bot: QQAndroidBot) : BotNetworkHandler
bot.groups.delegate.addLast( bot.groups.delegate.addLast(
@Suppress("DuplicatedCode") @Suppress("DuplicatedCode")
(GroupImpl( (GroupImpl(
bot = bot, bot = bot,
coroutineContext = bot.coroutineContext, coroutineContext = bot.coroutineContext,
id = troopNum.groupCode, id = troopNum.groupCode,
groupInfo = bot._lowLevelQueryGroupInfo(troopNum.groupCode).apply { groupInfo = bot._lowLevelQueryGroupInfo(troopNum.groupCode).apply {
this as GroupInfoImpl this as GroupInfoImpl
if (this.delegate.groupName == null) { if (this.delegate.groupName == null) {
this.delegate.groupName = troopNum.groupName this.delegate.groupName = troopNum.groupName
} }
if (this.delegate.groupMemo == null) { if (this.delegate.groupMemo == null) {
this.delegate.groupMemo = troopNum.groupMemo this.delegate.groupMemo = troopNum.groupMemo
} }
if (this.delegate.groupUin == null) { if (this.delegate.groupUin == null) {
this.delegate.groupUin = troopNum.groupUin this.delegate.groupUin = troopNum.groupUin
} }
this.delegate.groupCode = troopNum.groupCode this.delegate.groupCode = troopNum.groupCode
}, },
members = bot._lowLevelQueryGroupMemberList( members = bot._lowLevelQueryGroupMemberList(
troopNum.groupUin, troopNum.groupUin,
troopNum.groupCode, troopNum.groupCode,
troopNum.dwGroupOwnerUin troopNum.dwGroupOwnerUin
) )
)) ))
) )
}?.let { }?.let {
logger.error { "群${troopNum.groupCode}的列表拉取失败, 一段时间后将会重试" } logger.error { "群${troopNum.groupCode}的列表拉取失败, 一段时间后将会重试" }
......
...@@ -24,7 +24,7 @@ import net.mamoe.mirai.event.events.MemberJoinEvent ...@@ -24,7 +24,7 @@ import net.mamoe.mirai.event.events.MemberJoinEvent
import net.mamoe.mirai.getFriendOrNull import net.mamoe.mirai.getFriendOrNull
import net.mamoe.mirai.message.FriendMessage import net.mamoe.mirai.message.FriendMessage
import net.mamoe.mirai.message.data.MessageChain 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.QQAndroidBot
import net.mamoe.mirai.qqandroid.io.serialization.decodeUniPacket import net.mamoe.mirai.qqandroid.io.serialization.decodeUniPacket
import net.mamoe.mirai.qqandroid.io.serialization.readProtoBuf import net.mamoe.mirai.qqandroid.io.serialization.readProtoBuf
......
...@@ -19,10 +19,10 @@ import net.mamoe.mirai.data.Packet ...@@ -19,10 +19,10 @@ import net.mamoe.mirai.data.Packet
import net.mamoe.mirai.event.Event import net.mamoe.mirai.event.Event
import net.mamoe.mirai.event.events.* import net.mamoe.mirai.event.events.*
import net.mamoe.mirai.message.GroupMessage import net.mamoe.mirai.message.GroupMessage
import net.mamoe.mirai.qqandroid.GroupImpl import net.mamoe.mirai.qqandroid.contact.GroupImpl
import net.mamoe.mirai.qqandroid.MemberImpl import net.mamoe.mirai.qqandroid.contact.MemberImpl
import net.mamoe.mirai.qqandroid.QQAndroidBot 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.decodeUniPacket
import net.mamoe.mirai.qqandroid.io.serialization.readProtoBuf import net.mamoe.mirai.qqandroid.io.serialization.readProtoBuf
import net.mamoe.mirai.qqandroid.message.toMessageChain import net.mamoe.mirai.qqandroid.message.toMessageChain
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment