Internal optimizations

This commit is contained in:
Him188 2020-12-24 13:48:23 +08:00
parent 3ac188bb64
commit 89ec0b6a4f
11 changed files with 328 additions and 310 deletions

View File

@ -14,13 +14,14 @@ package net.mamoe.mirai.contact
import kotlinx.coroutines.CoroutineScope
import net.mamoe.kjbb.JvmBlockingBridge
import net.mamoe.mirai.Bot
import net.mamoe.mirai.LowLevelApi
import net.mamoe.mirai.data.MemberInfo
import net.mamoe.mirai.event.events.*
import net.mamoe.mirai.message.MessageReceipt
import net.mamoe.mirai.message.MessageReceipt.Companion.recall
import net.mamoe.mirai.message.data.*
import net.mamoe.mirai.utils.*
import net.mamoe.mirai.utils.ExternalImage
import net.mamoe.mirai.utils.MiraiExperimentalApi
import net.mamoe.mirai.utils.OverFileSizeMaxException
import net.mamoe.mirai.utils.PlannedRemoval
import java.io.InputStream
/**
@ -66,7 +67,7 @@ public interface Group : Contact, CoroutineScope {
* @see BotMuteEvent 机器人被禁言事件
* @see isBotMuted 判断机器人是否正在被禁言
*/
public val botMuteRemaining: Int
public val botMuteRemaining: Int get() = botAsMember.muteTimeRemaining
/**
* 机器人在这个群里的权限
@ -75,7 +76,7 @@ public interface Group : Contact, CoroutineScope {
*
* @see BotGroupPermissionChangeEvent 机器人群员修改
*/
public val botPermission: MemberPermission
public val botPermission: MemberPermission get() = botAsMember.permission
/**
* 群头像下载链接.
@ -135,14 +136,6 @@ public interface Group : Contact, CoroutineScope {
@JvmBlockingBridge
public suspend fun quit(): Boolean
/**
* 构造一个 [Member].
* 非特殊情况请不要使用这个函数. 优先使用 [get].
*/
@LowLevelApi
@MiraiExperimentalApi("dangerous")
public fun newMember(memberInfo: MemberInfo): Member
/**
* 向这个对象发送消息.
*

View File

@ -22,6 +22,7 @@ import net.mamoe.mirai.event.BroadcastControllable
import net.mamoe.mirai.internal.network.Packet
import net.mamoe.mirai.message.action.Nudge
import net.mamoe.mirai.utils.MiraiExperimentalApi
import net.mamoe.mirai.utils.MiraiInternalApi
import java.util.concurrent.atomic.AtomicBoolean
/**
@ -34,7 +35,7 @@ public sealed class BotLeaveEvent : BotEvent, Packet, AbstractEvent() {
* 机器人主动退出一个群.
*/
@MiraiExperimentalApi("目前此事件类型不一定正确. 部分被踢出情况也会广播此事件.")
public data class Active internal constructor(
public data class Active @MiraiInternalApi constructor(
public override val group: Group
) : BotLeaveEvent() {
public override fun toString(): String = "BotLeaveEvent.Active(group=${group.id})"
@ -44,7 +45,7 @@ public sealed class BotLeaveEvent : BotEvent, Packet, AbstractEvent() {
* 机器人被管理员或群主踢出群.
*/
@MiraiExperimentalApi("BotLeaveEvent 的子类可能在将来改动. 使用 BotLeaveEvent 以保证兼容性.")
public data class Kick internal constructor(
public data class Kick @MiraiInternalApi constructor(
public override val operator: Member
) : BotLeaveEvent(),
GroupOperableEvent {
@ -59,7 +60,7 @@ public sealed class BotLeaveEvent : BotEvent, Packet, AbstractEvent() {
/**
* Bot 在群里的权限被改变. 操作人一定是群主
*/
public data class BotGroupPermissionChangeEvent internal constructor(
public data class BotGroupPermissionChangeEvent @MiraiInternalApi constructor(
public override val group: Group,
public val origin: MemberPermission,
public val new: MemberPermission
@ -68,7 +69,7 @@ public data class BotGroupPermissionChangeEvent internal constructor(
/**
* Bot 被禁言
*/
public data class BotMuteEvent internal constructor(
public data class BotMuteEvent @MiraiInternalApi constructor(
public val durationSeconds: Int,
/**
* 操作人.
@ -82,7 +83,7 @@ public data class BotMuteEvent internal constructor(
/**
* Bot 被取消禁言
*/
public data class BotUnmuteEvent internal constructor(
public data class BotUnmuteEvent @MiraiInternalApi constructor(
/**
* 操作人.
*/
@ -102,7 +103,7 @@ public sealed class BotJoinGroupEvent : GroupEvent, BotPassiveEvent, Packet, Abs
* 不确定. 可能是主动加入
*/
@MiraiExperimentalApi
public data class Active internal constructor(
public data class Active @MiraiInternalApi constructor(
public override val group: Group
) : BotJoinGroupEvent() {
public override fun toString(): String = "BotJoinGroupEvent.Active(group=$group)"
@ -114,7 +115,7 @@ public sealed class BotJoinGroupEvent : GroupEvent, BotPassiveEvent, Packet, Abs
* 此时服务器基于 Bot QQ 设置自动同意了请求.
*/
@MiraiExperimentalApi
public data class Invite internal constructor(
public data class Invite @MiraiInternalApi constructor(
/**
* 邀请人
*/
@ -132,7 +133,7 @@ public sealed class BotJoinGroupEvent : GroupEvent, BotPassiveEvent, Packet, Abs
* [Bot] 是原群主
*/
@MiraiExperimentalApi
public data class Retrieve internal constructor(
public data class Retrieve @MiraiInternalApi constructor(
public override val group: Group
) : BotJoinGroupEvent() {
override fun toString(): String = "BotJoinGroupEvent.Retrieve(group=${group.id})"
@ -155,7 +156,7 @@ public interface GroupSettingChangeEvent<T> : GroupEvent, BotPassiveEvent, Broad
/**
* 群名改变. 此事件广播前修改就已经完成.
*/
public data class GroupNameChangeEvent internal constructor(
public data class GroupNameChangeEvent @MiraiInternalApi constructor(
public override val origin: String,
public override val new: String,
public override val group: Group,
@ -168,7 +169,7 @@ public data class GroupNameChangeEvent internal constructor(
/**
* 入群公告改变. 此事件广播前修改就已经完成.
*/
public data class GroupEntranceAnnouncementChangeEvent internal constructor(
public data class GroupEntranceAnnouncementChangeEvent @MiraiInternalApi constructor(
public override val origin: String,
public override val new: String,
public override val group: Group,
@ -182,7 +183,7 @@ public data class GroupEntranceAnnouncementChangeEvent internal constructor(
/**
* "全员禁言" 功能状态改变. 此事件广播前修改就已经完成.
*/
public data class GroupMuteAllEvent internal constructor(
public data class GroupMuteAllEvent @MiraiInternalApi constructor(
public override val origin: Boolean,
public override val new: Boolean,
public override val group: Group,
@ -196,7 +197,7 @@ public data class GroupMuteAllEvent internal constructor(
/**
* "匿名聊天" 功能状态改变. 此事件广播前修改就已经完成.
*/
public data class GroupAllowAnonymousChatEvent internal constructor(
public data class GroupAllowAnonymousChatEvent @MiraiInternalApi constructor(
public override val origin: Boolean,
public override val new: Boolean,
public override val group: Group,
@ -210,7 +211,7 @@ public data class GroupAllowAnonymousChatEvent internal constructor(
/**
* "坦白说" 功能状态改变. 此事件广播前修改就已经完成.
*/
public data class GroupAllowConfessTalkEvent internal constructor(
public data class GroupAllowConfessTalkEvent @MiraiInternalApi constructor(
public override val origin: Boolean,
public override val new: Boolean,
public override val group: Group,
@ -220,7 +221,7 @@ public data class GroupAllowConfessTalkEvent internal constructor(
/**
* "允许群员邀请好友加群" 功能状态改变. 此事件广播前修改就已经完成.
*/
public data class GroupAllowMemberInviteEvent internal constructor(
public data class GroupAllowMemberInviteEvent @MiraiInternalApi constructor(
public override val origin: Boolean,
public override val new: Boolean,
public override val group: Group,
@ -248,7 +249,7 @@ public sealed class MemberJoinEvent(
/**
* 被邀请加入群
*/
public data class Invite internal constructor(
public data class Invite @MiraiInternalApi constructor(
public override val member: NormalMember
) : MemberJoinEvent(member) {
public override fun toString(): String = "MemberJoinEvent.Invite(member=${member.id})"
@ -257,7 +258,7 @@ public sealed class MemberJoinEvent(
/**
* 成员主动加入群
*/
public data class Active internal constructor(
public data class Active @MiraiInternalApi constructor(
public override val member: NormalMember
) : MemberJoinEvent(member) {
public override fun toString(): String = "MemberJoinEvent.Active(member=${member.id})"
@ -267,7 +268,7 @@ public sealed class MemberJoinEvent(
* 原群主通过 https://huifu.qq.com/ 恢复原来群主身份并入群,
* 此时 [member] [Member.permission] 肯定是 [MemberPermission.OWNER]
*/
public data class Retrieve internal constructor(
public data class Retrieve @MiraiInternalApi constructor(
public override val member: NormalMember
) : MemberJoinEvent(member) {
override fun toString(): String = "MemberJoinEvent.Retrieve(member=${member.id})"
@ -305,7 +306,7 @@ public sealed class MemberLeaveEvent : GroupMemberEvent, AbstractEvent() {
* [Bot] 被邀请加入一个群.
*/
@Suppress("DEPRECATION")
public data class BotInvitedJoinGroupRequestEvent internal constructor(
public data class BotInvitedJoinGroupRequestEvent @MiraiInternalApi constructor(
public override val bot: Bot,
/**
* 事件唯一识别号
@ -341,7 +342,7 @@ public data class BotInvitedJoinGroupRequestEvent internal constructor(
* 一个账号请求加入群事件, [Bot] 在此群中是管理员或群主.
*/
@Suppress("DEPRECATION")
public data class MemberJoinRequestEvent internal constructor(
public data class MemberJoinRequestEvent @MiraiInternalApi constructor(
override val bot: Bot,
/**
* 事件唯一识别号
@ -401,7 +402,7 @@ public data class MemberJoinRequestEvent internal constructor(
*
* 由于服务器并不会告知名片变动, 此事件只能由 mirai 在发现变动时才广播. 不要依赖于这个事件.
*/
public data class MemberCardChangeEvent internal constructor(
public data class MemberCardChangeEvent @MiraiInternalApi constructor(
/**
* 修改前
*/
@ -418,7 +419,7 @@ public data class MemberCardChangeEvent internal constructor(
/**
* 成员群头衔改动. 一定为群主操作
*/
public data class MemberSpecialTitleChangeEvent internal constructor(
public data class MemberSpecialTitleChangeEvent @MiraiInternalApi constructor(
/**
* 修改前
*/
@ -447,7 +448,7 @@ public data class MemberSpecialTitleChangeEvent internal constructor(
/**
* 成员权限改变的事件. 成员不可能是机器人自己.
*/
public data class MemberPermissionChangeEvent internal constructor(
public data class MemberPermissionChangeEvent @MiraiInternalApi constructor(
public override val member: Member,
public val origin: MemberPermission,
public val new: MemberPermission
@ -463,7 +464,7 @@ public data class MemberPermissionChangeEvent internal constructor(
*
* @see BotMuteEvent 机器人被禁言的事件
*/
public data class MemberMuteEvent internal constructor(
public data class MemberMuteEvent @MiraiInternalApi constructor(
public override val member: Member,
public val durationSeconds: Int,
/**
@ -477,7 +478,7 @@ public data class MemberMuteEvent internal constructor(
*
* @see BotUnmuteEvent 机器人被取消禁言的事件
*/
public data class MemberUnmuteEvent internal constructor(
public data class MemberUnmuteEvent @MiraiInternalApi constructor(
public override val member: Member,
/**
* 操作人. null 则为机器人操作
@ -494,7 +495,7 @@ public data class MemberUnmuteEvent internal constructor(
* [Member] [][Nudge] 的事件.
*/
@MiraiExperimentalApi
public data class MemberNudgedEvent internal constructor(
public data class MemberNudgedEvent @MiraiInternalApi constructor(
/**
* 戳一戳的发起人, 不可能是 bot
*/

View File

@ -20,10 +20,7 @@ import net.mamoe.mirai.data.*
import net.mamoe.mirai.event.events.BotInvitedJoinGroupRequestEvent
import net.mamoe.mirai.event.events.MemberJoinRequestEvent
import net.mamoe.mirai.event.events.NewFriendRequestEvent
import net.mamoe.mirai.internal.contact.FriendImpl
import net.mamoe.mirai.internal.contact.GroupImpl
import net.mamoe.mirai.internal.contact.MemberInfoImpl
import net.mamoe.mirai.internal.contact.checkIsGroupImpl
import net.mamoe.mirai.internal.contact.*
import net.mamoe.mirai.internal.message.*
import net.mamoe.mirai.internal.network.highway.HighwayHelper
import net.mamoe.mirai.internal.network.protocol.data.proto.ImMsgBody
@ -709,17 +706,17 @@ internal open class MiraiImpl : IMirai, LowLevelApiAccessor {
}
if (accept ?: return@run)
groups[groupId]?.apply {
members.delegate.add(newMember(object : MemberInfo {
override val nameCard: String get() = ""
override val permission: MemberPermission get() = MemberPermission.MEMBER
override val specialTitle: String get() = ""
override val muteTimestamp: Int get() = 0
override val uin: Long get() = fromId
override val nick: String get() = fromNick
override val remark: String
get() = ""
}).cast())
groups[groupId]?.run {
members.delegate.add(
newMember(
MemberInfoImpl(
uin = fromId,
nick = fromNick,
permission = MemberPermission.MEMBER,
"", "", "", 0, null
)
).cast()
)
}
}

View File

@ -12,7 +12,6 @@
package net.mamoe.mirai.internal.contact
import kotlinx.coroutines.launch
import net.mamoe.mirai.LowLevelApi
import net.mamoe.mirai.contact.*
import net.mamoe.mirai.data.GroupInfo
@ -26,7 +25,6 @@ import net.mamoe.mirai.internal.message.OfflineGroupImage
import net.mamoe.mirai.internal.message.ensureSequenceIdAvailable
import net.mamoe.mirai.internal.message.firstIsInstanceOrNull
import net.mamoe.mirai.internal.network.highway.HighwayHelper
import net.mamoe.mirai.internal.network.protocol.packet.chat.TroopManagement
import net.mamoe.mirai.internal.network.protocol.packet.chat.image.ImgStore
import net.mamoe.mirai.internal.network.protocol.packet.chat.receive.MessageSvcPbSendMsg
import net.mamoe.mirai.internal.network.protocol.packet.chat.receive.createToGroup
@ -46,16 +44,12 @@ import kotlin.coroutines.CoroutineContext
import kotlin.time.ExperimentalTime
internal fun GroupImpl.Companion.checkIsInstance(instance: Group) {
contract {
returns() implies (instance is GroupImpl)
}
contract { returns() implies (instance is GroupImpl) }
check(instance is GroupImpl) { "group is not an instanceof GroupImpl!! DO NOT interlace two or more protocol implementations!!" }
}
internal fun Group.checkIsGroupImpl() {
contract {
returns() implies (this@checkIsGroupImpl is GroupImpl)
}
contract { returns() implies (this@checkIsGroupImpl is GroupImpl) }
GroupImpl.checkIsInstance(this)
}
@ -69,20 +63,14 @@ internal class GroupImpl(
) : Group, AbstractContact(bot, coroutineContext) {
companion object
val groupPkgMsgParsingCache = GroupPkgMsgParsingCache()
val uin: Long = groupInfo.uin
override val settings: GroupSettingsImpl = GroupSettingsImpl(this, groupInfo)
override var name: String by settings::name
override lateinit var owner: NormalMember
override lateinit var botAsMember: NormalMember
override val botPermission: MemberPermission get() = botAsMember.permission
// e.g. 600
override val botMuteRemaining: Int get() = botAsMember.muteTimeRemaining
override val members: ContactList<NormalMember> = ContactList(members.mapNotNull {
override val members: ContactList<NormalMember> = ContactList(members.mapNotNullTo(ConcurrentLinkedQueue()) {
if (it.uin == bot.id) {
botAsMember = newMember(it).cast()
if (it.permission == MemberPermission.OWNER) {
@ -94,115 +82,9 @@ internal class GroupImpl(
owner = member
}
}
}.mapTo(ConcurrentLinkedQueue()) { it })
})
internal var _name: String = groupInfo.name
private var _announcement: String = groupInfo.memo
private var _allowMemberInvite: Boolean = groupInfo.allowMemberInvite
internal var _confessTalk: Boolean = groupInfo.confessTalk
internal var _muteAll: Boolean = groupInfo.muteAll
private var _autoApprove: Boolean = groupInfo.autoApprove
internal var _anonymousChat: Boolean = groupInfo.allowAnonymousChat
override var name: String
get() = _name
set(newValue) {
checkBotPermission(MemberPermission.ADMINISTRATOR)
if (_name != newValue) {
val oldValue = _name
_name = newValue
launch {
bot.network.run {
TroopManagement.GroupOperation.name(
client = bot.client,
groupCode = id,
newName = newValue
).sendWithoutExpect()
}
GroupNameChangeEvent(oldValue, newValue, this@GroupImpl, null).broadcast()
}
}
}
override val settings: GroupSettings = object : GroupSettings {
override var entranceAnnouncement: String
get() = _announcement
set(newValue) {
checkBotPermission(MemberPermission.ADMINISTRATOR)
//if (_announcement != newValue) {
val oldValue = _announcement
_announcement = newValue
launch {
bot.network.run {
TroopManagement.GroupOperation.memo(
client = bot.client,
groupCode = id,
newMemo = newValue
).sendWithoutExpect()
}
GroupEntranceAnnouncementChangeEvent(oldValue, newValue, this@GroupImpl, null).broadcast()
}
//}
}
override var isAllowMemberInvite: Boolean
get() = _allowMemberInvite
set(newValue) {
checkBotPermission(MemberPermission.ADMINISTRATOR)
//if (_allowMemberInvite != newValue) {
val oldValue = _allowMemberInvite
_allowMemberInvite = newValue
launch {
bot.network.run {
TroopManagement.GroupOperation.allowMemberInvite(
client = bot.client,
groupCode = id,
switch = newValue
).sendWithoutExpect()
}
GroupAllowMemberInviteEvent(oldValue, newValue, this@GroupImpl, null).broadcast()
}
//}
}
override var isAnonymousChatEnabled: Boolean
get() = _anonymousChat
@Suppress("UNUSED_PARAMETER")
set(newValue) {
TODO()
}
override var isAutoApproveEnabled: Boolean
get() = _autoApprove
@Suppress("UNUSED_PARAMETER")
set(newValue) {
TODO()
}
override var isMuteAll: Boolean
get() = _muteAll
set(newValue) {
checkBotPermission(MemberPermission.ADMINISTRATOR)
//if (_muteAll != newValue) {
val oldValue = _muteAll
_muteAll = newValue
launch {
bot.network.run {
TroopManagement.GroupOperation.muteAll(
client = bot.client,
groupCode = id,
switch = newValue
).sendWithoutExpect()
}
GroupMuteAllEvent(oldValue, newValue, this@GroupImpl, null).broadcast()
}
//}
}
}
val groupPkgMsgParsingCache = GroupPkgMsgParsingCache()
override suspend fun quit(): Boolean {
check(botPermission != MemberPermission.OWNER) { "An owner cannot quit from a owning group" }
@ -225,33 +107,6 @@ internal class GroupImpl(
return true
}
override fun newMember(memberInfo: MemberInfo): Member {
memberInfo.anonymousId?.let { anId ->
return AnonymousMemberImpl(
this, this.coroutineContext,
memberInfo, anId
)
}
return MemberImpl(
this,
this.coroutineContext,
memberInfo
)
}
internal fun newAnonymous(name: String, id: String): Member = newMember(
object : MemberInfo {
override val nameCard = name
override val permission = MemberPermission.MEMBER
override val specialTitle = "匿名"
override val muteTimestamp = 0
override val uin = 80000000L
override val nick = name
override val remark: String = "匿名"
override val anonymousId: String get() = id
}
)
override operator fun get(id: Long): NormalMember? {
if (id == bot.id) {
return botAsMember
@ -460,6 +315,33 @@ internal class GroupImpl(
}
override fun toString(): String = "Group($id)"
}
internal fun Group.newMember(memberInfo: MemberInfo): Member {
this.checkIsGroupImpl()
memberInfo.anonymousId?.let { anId ->
return AnonymousMemberImpl(
this, this.coroutineContext,
memberInfo, anId
)
}
return NormalMemberImpl(
this,
this.coroutineContext,
memberInfo
)
}
internal fun GroupImpl.newAnonymous(name: String, id: String): Member = newMember(
MemberInfoImpl(
uin = 80000000L,
nick = name,
permission = MemberPermission.MEMBER,
remark = "匿名",
nameCard = name,
specialTitle = "匿名",
muteTimestamp = 0,
anonymousId = id,
)
)

View File

@ -0,0 +1,135 @@
/*
* Copyright 2019-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.internal.contact
import kotlinx.coroutines.launch
import net.mamoe.mirai.contact.GroupSettings
import net.mamoe.mirai.contact.MemberPermission
import net.mamoe.mirai.contact.checkBotPermission
import net.mamoe.mirai.data.GroupInfo
import net.mamoe.mirai.event.broadcast
import net.mamoe.mirai.event.events.GroupAllowMemberInviteEvent
import net.mamoe.mirai.event.events.GroupEntranceAnnouncementChangeEvent
import net.mamoe.mirai.event.events.GroupMuteAllEvent
import net.mamoe.mirai.event.events.GroupNameChangeEvent
import net.mamoe.mirai.internal.network.protocol.packet.chat.TroopManagement
@Suppress("SetterBackingFieldAssignment")
internal class GroupSettingsImpl(
private val group: GroupImpl,
groupInfo: GroupInfo,
) : GroupSettings {
internal var nameField: String = groupInfo.name
var name: String
get() = nameField
set(newValue) = with(group) {
checkBotPermission(MemberPermission.ADMINISTRATOR)
if (nameField != newValue) {
val oldValue = nameField
nameField = newValue
launch {
bot.network.run {
TroopManagement.GroupOperation.name(
client = bot.client,
groupCode = id,
newName = newValue
).sendWithoutExpect()
}
GroupNameChangeEvent(oldValue, newValue, group, null).broadcast()
}
}
}
private var _entranceAnnouncement: String = groupInfo.memo
@Deprecated("Don't use public var internally", level = DeprecationLevel.HIDDEN)
override var entranceAnnouncement: String
get() = _entranceAnnouncement
set(newValue) = with(group) {
checkBotPermission(MemberPermission.ADMINISTRATOR)
//if (_announcement != newValue) {
val oldValue = _entranceAnnouncement
_entranceAnnouncement = newValue
launch {
bot.network.run {
TroopManagement.GroupOperation.memo(
client = bot.client,
groupCode = id,
newMemo = newValue
).sendWithoutExpect()
}
GroupEntranceAnnouncementChangeEvent(oldValue, newValue, group, null).broadcast()
}
//}
}
@Deprecated("Don't use public var internally", level = DeprecationLevel.HIDDEN)
override var isAllowMemberInvite: Boolean = groupInfo.allowMemberInvite
set(newValue) = with(group) {
checkBotPermission(MemberPermission.ADMINISTRATOR)
//if (_allowMemberInvite != newValue) {
val oldValue = field
field = newValue
launch {
bot.network.run {
TroopManagement.GroupOperation.allowMemberInvite(
client = bot.client,
groupCode = id,
switch = newValue
).sendWithoutExpect()
}
GroupAllowMemberInviteEvent(oldValue, newValue, group, null).broadcast()
}
//}
}
internal var isAnonymousChatEnabledField: Boolean = groupInfo.allowAnonymousChat
@Deprecated("Don't use public var internally", level = DeprecationLevel.HIDDEN)
override var isAnonymousChatEnabled: Boolean
get() = isAnonymousChatEnabledField
@Suppress("UNUSED_PARAMETER")
set(newValue) {
throw UnsupportedOperationException()
}
@Deprecated("Don't use public var internally", level = DeprecationLevel.HIDDEN)
override var isAutoApproveEnabled: Boolean = groupInfo.autoApprove
@Suppress("UNUSED_PARAMETER")
set(newValue) {
throw UnsupportedOperationException()
}
internal var isMuteAllField: Boolean = groupInfo.muteAll
@Deprecated("Don't use public var internally", level = DeprecationLevel.HIDDEN)
override var isMuteAll: Boolean
get() = isMuteAllField
set(newValue) = with(group) {
checkBotPermission(MemberPermission.ADMINISTRATOR)
//if (_muteAll != newValue) {
val oldValue = isMuteAllField
isMuteAllField = newValue
launch {
bot.network.run {
TroopManagement.GroupOperation.muteAll(
client = bot.client,
groupCode = id,
switch = newValue
).sendWithoutExpect()
}
GroupMuteAllEvent(oldValue, newValue, group, null).broadcast()
}
//}
}
}

View File

@ -0,0 +1,43 @@
/*
* Copyright 2019-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.internal.contact
import net.mamoe.mirai.contact.MemberPermission
import net.mamoe.mirai.data.MemberInfo
import net.mamoe.mirai.internal.network.protocol.data.jce.StTroopMemberInfo
internal class MemberInfoImpl(
override val uin: Long,
override var nick: String,
override val permission: MemberPermission,
override val remark: String,
override val nameCard: String,
override val specialTitle: String,
override val muteTimestamp: Int,
override val anonymousId: String?,
) : MemberInfo {
constructor(
jceInfo: StTroopMemberInfo,
groupOwnerId: Long
) : this(
uin = jceInfo.memberUin,
nick = jceInfo.nick,
permission = when {
jceInfo.memberUin == groupOwnerId -> MemberPermission.OWNER
jceInfo.dwFlag == 1L -> MemberPermission.ADMINISTRATOR
else -> MemberPermission.MEMBER
},
remark = jceInfo.autoRemark.orEmpty(),
nameCard = jceInfo.sName.orEmpty(),
specialTitle = jceInfo.sSpecialTitle.orEmpty(),
muteTimestamp = jceInfo.dwShutupTimestap?.toInt() ?: 0,
anonymousId = null,
)
}

View File

@ -22,7 +22,6 @@ import net.mamoe.mirai.event.events.*
import net.mamoe.mirai.internal.message.MessageSourceToTempImpl
import net.mamoe.mirai.internal.message.ensureSequenceIdAvailable
import net.mamoe.mirai.internal.message.firstIsInstanceOrNull
import net.mamoe.mirai.internal.network.protocol.data.jce.StTroopMemberInfo
import net.mamoe.mirai.internal.network.protocol.packet.chat.TroopManagement
import net.mamoe.mirai.internal.network.protocol.packet.chat.receive.MessageSvcPbSendMsg
import net.mamoe.mirai.internal.network.protocol.packet.chat.receive.createToTemp
@ -37,7 +36,7 @@ import kotlin.coroutines.CoroutineContext
@OptIn(LowLevelApi::class)
@Suppress("MemberVisibilityCanBePrivate")
internal class MemberImpl constructor(
internal class NormalMemberImpl constructor(
group: GroupImpl,
coroutineContext: CoroutineContext,
memberInfo: MemberInfo
@ -80,7 +79,7 @@ internal class MemberImpl constructor(
val source: MessageSourceToTempImpl
MessageSvcPbSendMsg.createToTemp(
bot.client,
this@MemberImpl,
this@NormalMemberImpl,
chain
) {
source = it
@ -89,7 +88,7 @@ internal class MemberImpl constructor(
"Send temp message failed: $it"
}
}
MessageReceipt(source, this@MemberImpl)
MessageReceipt(source, this@NormalMemberImpl)
}
result.fold(
@ -138,11 +137,11 @@ internal class MemberImpl constructor(
bot.network.run {
TroopManagement.EditGroupNametag(
bot.client,
this@MemberImpl,
this@NormalMemberImpl,
newValue
).sendWithoutExpect()
}
MemberCardChangeEvent(oldValue, newValue, this@MemberImpl).broadcast()
MemberCardChangeEvent(oldValue, newValue, this@NormalMemberImpl).broadcast()
}
}
}
@ -158,16 +157,15 @@ internal class MemberImpl constructor(
bot.network.run {
TroopManagement.EditSpecialTitle(
bot.client,
this@MemberImpl,
this@NormalMemberImpl,
newValue
).sendWithoutExpect()
}
MemberSpecialTitleChangeEvent(oldValue, newValue, this@MemberImpl, null).broadcast()
MemberSpecialTitleChangeEvent(oldValue, newValue, this@NormalMemberImpl, null).broadcast()
}
}
}
@JvmSynthetic
override suspend fun mute(durationSeconds: Int) {
check(this.id != bot.id) {
"A bot can't mute itself."
@ -177,32 +175,30 @@ internal class MemberImpl constructor(
TroopManagement.Mute(
client = bot.client,
groupCode = group.id,
memberUin = this@MemberImpl.id,
memberUin = this@NormalMemberImpl.id,
timeInSecond = durationSeconds
).sendAndExpect<TroopManagement.Mute.Response>()
}
@Suppress("RemoveRedundantQualifierName") // or unresolved reference
net.mamoe.mirai.event.events.MemberMuteEvent(this@MemberImpl, durationSeconds, null).broadcast()
net.mamoe.mirai.event.events.MemberMuteEvent(this@NormalMemberImpl, durationSeconds, null).broadcast()
}
@JvmSynthetic
override suspend fun unmute() {
checkBotPermissionHigherThanThis("unmute")
bot.network.run {
TroopManagement.Mute(
client = bot.client,
groupCode = group.id,
memberUin = this@MemberImpl.id,
memberUin = this@NormalMemberImpl.id,
timeInSecond = 0
).sendAndExpect<TroopManagement.Mute.Response>()
}
@Suppress("RemoveRedundantQualifierName") // or unresolved reference
net.mamoe.mirai.event.events.MemberUnmuteEvent(this@MemberImpl, null).broadcast()
net.mamoe.mirai.event.events.MemberUnmuteEvent(this@NormalMemberImpl, null).broadcast()
}
@JvmSynthetic
override suspend fun kick(message: String) {
checkBotPermissionHigherThanThis("kick")
check(group.members[this.id] != null) {
@ -211,16 +207,16 @@ internal class MemberImpl constructor(
bot.network.run {
val response: TroopManagement.Kick.Response = TroopManagement.Kick(
client = bot.client,
member = this@MemberImpl,
member = this@NormalMemberImpl,
message = message
).sendAndExpect()
check(response.success) { "kick failed: ${response.ret}" }
@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
group.members.delegate.removeIf { it.id == this@MemberImpl.id }
this@MemberImpl.cancel(CancellationException("Kicked by bot"))
MemberLeaveEvent.Kick(this@MemberImpl, null).broadcast()
group.members.delegate.removeIf { it.id == this@NormalMemberImpl.id }
this@NormalMemberImpl.cancel(CancellationException("Kicked by bot"))
MemberLeaveEvent.Kick(this@NormalMemberImpl, null).broadcast()
}
}
}
@ -235,29 +231,11 @@ internal fun Member.checkBotPermissionHigherThanThis(operationName: String) {
}
@OptIn(ExperimentalContracts::class)
internal fun Member.checkIsMemberImpl(): MemberImpl {
internal fun Member.checkIsMemberImpl(): NormalMemberImpl {
contract {
returns() implies (this@checkIsMemberImpl is MemberImpl)
returns() implies (this@checkIsMemberImpl is NormalMemberImpl)
}
check(this is MemberImpl) { "A Member instance is not instance of MemberImpl. Don't interlace two protocol implementations together!" }
check(this is NormalMemberImpl) { "A Member instance is not instance of MemberImpl. Don't interlace two protocol implementations together!" }
return this
}
@OptIn(LowLevelApi::class)
internal class MemberInfoImpl(
jceInfo: StTroopMemberInfo,
groupOwnerId: Long
) : MemberInfo {
override val uin: Long = jceInfo.memberUin
override val nameCard: String = jceInfo.sName ?: ""
internal var _nick: String = jceInfo.nick
override val nick: String get() = _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
override val remark: String = jceInfo.autoRemark ?: ""
}

View File

@ -15,6 +15,7 @@ import net.mamoe.mirai.Bot
import net.mamoe.mirai.contact.Friend
import net.mamoe.mirai.contact.Member
import net.mamoe.mirai.internal.contact.GroupImpl
import net.mamoe.mirai.internal.contact.newAnonymous
import net.mamoe.mirai.internal.network.protocol.data.proto.ImMsgBody
import net.mamoe.mirai.internal.network.protocol.data.proto.MsgComm
import net.mamoe.mirai.internal.network.protocol.data.proto.SourceMsg

View File

@ -23,7 +23,8 @@ import net.mamoe.mirai.event.events.GroupMessageSyncEvent
import net.mamoe.mirai.event.events.MemberCardChangeEvent
import net.mamoe.mirai.internal.QQAndroidBot
import net.mamoe.mirai.internal.contact.GroupImpl
import net.mamoe.mirai.internal.contact.MemberImpl
import net.mamoe.mirai.internal.contact.NormalMemberImpl
import net.mamoe.mirai.internal.contact.newAnonymous
import net.mamoe.mirai.internal.message.toMessageChain
import net.mamoe.mirai.internal.network.Packet
import net.mamoe.mirai.internal.network.protocol.data.proto.ImMsgBody
@ -101,7 +102,7 @@ internal object OnlinePushPbPushGroupMsg : IncomingPacketFactory<Packet?>("Onlin
sender = group.newAnonymous(anonymous.anonNick.encodeToString(), anonymous.anonId.encodeToBase64())
name = sender.nameCard
} else { // normal member chat
sender = group[msgHead.fromUin] as MemberImpl
sender = group[msgHead.fromUin] as NormalMemberImpl
name = findSenderName(extraInfo, msgHead.groupInfo) ?: sender.nameCardOrNick
}
@ -129,7 +130,7 @@ internal object OnlinePushPbPushGroupMsg : IncomingPacketFactory<Packet?>("Onlin
private suspend inline fun broadcastNameCardChangedEventIfNecessary(sender: Member, name: String) {
val currentNameCard = sender.nameCard
if (sender is MemberImpl && name != currentNameCard) {
if (sender is NormalMemberImpl && name != currentNameCard) {
sender._nameCard = name
MemberCardChangeEvent(currentNameCard, name, sender).broadcast()
}

View File

@ -24,8 +24,9 @@ import net.mamoe.mirai.data.MemberInfo
import net.mamoe.mirai.event.events.*
import net.mamoe.mirai.internal.QQAndroidBot
import net.mamoe.mirai.internal.contact.GroupImpl
import net.mamoe.mirai.internal.contact.MemberImpl
import net.mamoe.mirai.internal.contact.NormalMemberImpl
import net.mamoe.mirai.internal.contact.checkIsMemberImpl
import net.mamoe.mirai.internal.contact.newMember
import net.mamoe.mirai.internal.message.contextualBugReportException
import net.mamoe.mirai.internal.network.MultiPacketByIterable
import net.mamoe.mirai.internal.network.Packet
@ -100,7 +101,7 @@ internal object OnlinePushPbPushTransMsg :
)
)
} else {
val member = group[from] as MemberImpl
val member = group[from] as NormalMemberImpl
if (member.permission != MemberPermission.MEMBER) {
results.add(
MemberPermissionChangeEvent(
@ -186,7 +187,7 @@ internal object OnlinePushPbPushTransMsg :
newPermission
)
} else {
val member = group[target] as MemberImpl
val member = group[target] as NormalMemberImpl
if (member.permission == newPermission) {
return null
}
@ -230,7 +231,7 @@ internal object OnlinePushPbPushTransMsg :
bot.groups.delegate.remove(group)
}
} else {
val member = group.get(target) as? MemberImpl ?: return null
val member = group.get(target) as? NormalMemberImpl ?: return null
return MemberLeaveEvent.Quit(member.also {
member.cancel(CancellationException("Leaved actively"))
group.members.delegate.remove(member)
@ -245,7 +246,7 @@ internal object OnlinePushPbPushTransMsg :
bot.groups.delegate.remove(group)
}
} else {
val member = group.get(target) as? MemberImpl ?: return null
val member = group.get(target) as? NormalMemberImpl ?: return null
return MemberLeaveEvent.Kick(member.also {
member.cancel(CancellationException("Being kicked"))
group.members.delegate.remove(member)

View File

@ -45,13 +45,9 @@ import net.mamoe.mirai.internal.network.protocol.packet.IncomingPacketFactory
import net.mamoe.mirai.internal.network.protocol.packet.OutgoingPacket
import net.mamoe.mirai.internal.network.protocol.packet.buildResponseUniPacket
import net.mamoe.mirai.internal.utils.*
import net.mamoe.mirai.internal.utils._miraiContentToString
import net.mamoe.mirai.internal.utils.encodeToString
import net.mamoe.mirai.internal.utils.io.ProtoBuf
import net.mamoe.mirai.internal.utils.io.readString
import net.mamoe.mirai.internal.utils.io.serialization.*
import net.mamoe.mirai.internal.utils.read
import net.mamoe.mirai.internal.utils.toUHexString
import net.mamoe.mirai.utils.currentTimeSeconds
import net.mamoe.mirai.utils.debug
import net.mamoe.mirai.utils.mapToIntArray
@ -89,7 +85,7 @@ internal object OnlinePushReqPush : IncomingPacketFactory<OnlinePushReqPush.ReqP
val group = bot.getGroup(readUInt().toLong())
?: return@deco emptySequence() // group has not been initialized
GroupImpl.checkIsInstance(group)
group.checkIsGroupImpl()
val internalType = readByte().toInt()
discardExact(1)
@ -191,10 +187,10 @@ private object Transformers732 : Map<Int, Lambda732> by mapOf(
if (target == 0L) {
val new = timeSeconds != 0
if (group.settings.isMuteAll == new) {
if (group.settings.isMuteAllField == new) {
return@lambda732 emptySequence()
}
group._muteAll = new
group.settings.isMuteAllField = new
return@lambda732 sequenceOf(GroupMuteAllEvent(!new, new, group, operator))
}
@ -230,11 +226,11 @@ private object Transformers732 : Map<Int, Lambda732> by mapOf(
// 匿名
val operator = group[readUInt().toLong()] ?: return@lambda732 emptySequence()
val new = readInt() == 0
if (group.settings.isAnonymousChatEnabled == new) {
if (group.settings.isAnonymousChatEnabledField == new) {
return@lambda732 emptySequence()
}
group._anonymousChat = new
group.settings.isAnonymousChatEnabledField = new
return@lambda732 sequenceOf(GroupAllowAnonymousChatEvent(!new, new, group, operator))
},
@ -409,6 +405,7 @@ internal inline fun lambda528(crossinline block: MsgType0x210.(QQAndroidBot, Msg
/**
* @see MsgType0x210
*/
@OptIn(ExperimentalStdlibApi::class)
internal object Transformers528 : Map<Long, Lambda528> by mapOf(
0x8AL to lambda528 { bot ->
@ -606,7 +603,7 @@ internal object Transformers528 : Map<Long, Lambda528> by mapOf(
val operator = if (this.cmdUin == bot.id) null
else group[this.cmdUin] ?: return@mapNotNull null
group._name = new
group.settings.nameField = new
return@mapNotNull GroupNameChangeEvent(old, new, group, operator)
}
@ -688,57 +685,46 @@ internal object Transformers528 : Map<Long, Lambda528> by mapOf(
return sequenceOf(FriendAvatarChangedEvent(friend))
}
fun ModProfile.transform(bot: QQAndroidBot): Sequence<Packet> {
return ArrayList<Packet>().apply {
var containsUnknown = false
msgProfileInfos.forEach { modified ->
when (modified.field) {
20002 -> { // 昵称修改
val value = modified.value
val to = value.encodeToString()
if (uin == bot.id) {
val from = bot.nick
if (from != to) {
bot.nick = to
add(BotNickChangedEvent(bot, from, to))
}
} else {
val friend = (bot.getFriend(uin) ?: return@forEach) as FriendImpl
val info = friend.friendInfo
val from = info.nick
when (info) {
is FriendInfoImpl -> {
info.nick = to
}
is MemberInfoImpl -> {
info._nick = to
}
else -> {
bot.network.logger.debug {
"Unknown how to update nick for $info"
}
}
}
add(
FriendNickChangedEvent(
friend, from, to
)
)
fun ModProfile.transform(bot: QQAndroidBot): Sequence<Packet> = buildList<Packet> {
var containsUnknown = false
msgProfileInfos.forEach { modified ->
when (modified.field) {
20002 -> { // 昵称修改
val value = modified.value
val to = value.encodeToString()
if (uin == bot.id) {
val from = bot.nick
if (from != to) {
bot.nick = to
add(BotNickChangedEvent(bot, from, to))
}
}
else -> {
containsUnknown = true
} else {
val friend = (bot.getFriend(uin) ?: return@forEach) as FriendImpl
val info = friend.friendInfo
val from = info.nick
when (info) {
is FriendInfoImpl -> info.nick = to
is MemberInfoImpl -> info.nick = to
else -> {
bot.network.logger.debug {
"Unknown how to update nick for $info"
}
}
}
add(FriendNickChangedEvent(friend, from, to))
}
}
}
if (msgProfileInfos.isEmpty() || containsUnknown) {
bot.network.logger.debug {
"Transformers528 0x27L: new data: ${_miraiContentToString()}"
else -> {
containsUnknown = true
}
}
}.asSequence()
}
}
if (msgProfileInfos.isEmpty() || containsUnknown) {
bot.network.logger.debug {
"Transformers528 0x27L: new data: ${_miraiContentToString()}"
}
}
}.asSequence()
return@lambda528 vProtobuf.loadAs(SubMsgType0x27MsgBody.serializer()).msgModInfos.asSequence()
.flatMap {