mirror of
https://github.com/mamoe/mirai.git
synced 2025-02-01 12:00:34 +08:00
Group management Update
This commit is contained in:
parent
30d41f6e9d
commit
5c04ba445c
@ -1,5 +1,7 @@
|
||||
package net.mamoe.mirai.qqandroid
|
||||
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.launch
|
||||
import net.mamoe.mirai.contact.*
|
||||
import net.mamoe.mirai.data.FriendNameRemark
|
||||
import net.mamoe.mirai.data.PreviousNameList
|
||||
@ -23,6 +25,7 @@ import net.mamoe.mirai.utils.io.PlatformSocket
|
||||
import net.mamoe.mirai.utils.io.discardExact
|
||||
import net.mamoe.mirai.utils.unsafeWeakRef
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
import kotlin.properties.Delegates
|
||||
|
||||
internal abstract class ContactImpl : Contact
|
||||
|
||||
@ -108,15 +111,106 @@ internal class MemberImpl(
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 对GroupImpl
|
||||
* 中name/announcement的更改会直接向服务器异步汇报
|
||||
*/
|
||||
@UseExperimental(MiraiInternalAPI::class)
|
||||
internal class GroupImpl(
|
||||
bot: QQAndroidBot, override val coroutineContext: CoroutineContext,
|
||||
override val id: Long,
|
||||
val uin: Long,
|
||||
override var name: String,
|
||||
override var announcement: String,
|
||||
initName: String,
|
||||
initAnnouncement: String,
|
||||
initAllowMemberInvite: Boolean,
|
||||
initConfessTalk: Boolean,
|
||||
initMuteAll: Boolean,
|
||||
initAutoApprove: Boolean,
|
||||
initAnonymousChat: Boolean,
|
||||
override var members: ContactList<Member>
|
||||
) : ContactImpl(), Group {
|
||||
|
||||
override var name by Delegates.observable(initName) { _, oldValue, newValue ->
|
||||
if (this.botPermission != MemberPermission.MEMBER && oldValue != newValue) {
|
||||
this.bot.launch {
|
||||
bot.network.run {
|
||||
TroopManagement.updateGroupInfo.name(
|
||||
client = bot.client,
|
||||
groupCode = id,
|
||||
newName = newValue
|
||||
).sendWithoutExpect()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override var announcement: String by Delegates.observable(initAnnouncement) { _, oldValue, newValue ->
|
||||
if (this.botPermission != MemberPermission.MEMBER && oldValue != newValue) {
|
||||
this.bot.launch {
|
||||
bot.network.run {
|
||||
TroopManagement.updateGroupInfo.memo(
|
||||
client = bot.client,
|
||||
groupCode = id,
|
||||
newMemo = newValue
|
||||
).sendWithoutExpect()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
override var allowMemberInvite: Boolean by Delegates.observable(initAllowMemberInvite) { _, oldValue, newValue ->
|
||||
if (this.botPermission != MemberPermission.MEMBER && oldValue != newValue) {
|
||||
this.bot.launch {
|
||||
bot.network.run {
|
||||
TroopManagement.updateGroupInfo.allowMemberInvite(
|
||||
client = bot.client,
|
||||
groupCode = id,
|
||||
switch = newValue
|
||||
).sendWithoutExpect()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override var autoApprove: Boolean by Delegates.observable(initAutoApprove) { _, oldValue, newValue ->
|
||||
//暂时也不能改
|
||||
}
|
||||
|
||||
override val anonymousChat: Boolean by Delegates.observable(initAnonymousChat) { _, oldValue, newValue ->
|
||||
//暂时不能改
|
||||
}
|
||||
|
||||
override var confessTalk: Boolean by Delegates.observable(initConfessTalk) { _, oldValue, newValue ->
|
||||
if (this.botPermission != MemberPermission.MEMBER && oldValue != newValue) {
|
||||
this.bot.launch {
|
||||
bot.network.run {
|
||||
TroopManagement.updateGroupInfo.confessTalk(
|
||||
client = bot.client,
|
||||
groupCode = id,
|
||||
switch = newValue
|
||||
).sendWithoutExpect()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
override var muteAll: Boolean by Delegates.observable(initMuteAll) { _, oldValue, newValue ->
|
||||
if (this.botPermission != MemberPermission.MEMBER && oldValue != newValue) {
|
||||
this.bot.launch {
|
||||
bot.network.run {
|
||||
TroopManagement.updateGroupInfo.muteAll(
|
||||
client = bot.client,
|
||||
groupCode = id,
|
||||
switch = newValue
|
||||
).sendWithoutExpect()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
override lateinit var owner: Member
|
||||
override var botPermission: MemberPermission = MemberPermission.MEMBER
|
||||
|
||||
@ -124,6 +218,7 @@ internal class GroupImpl(
|
||||
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
|
||||
override operator fun get(id: Long): Member {
|
||||
return members.delegate.filteringGetOrNull { it.id == id } ?: throw NoSuchElementException("for group id $id")
|
||||
}
|
||||
|
@ -24,6 +24,7 @@ import net.mamoe.mirai.qqandroid.event.ForceOfflineEvent
|
||||
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.*
|
||||
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.qqandroid.network.protocol.packet.list.FriendList
|
||||
import net.mamoe.mirai.qqandroid.network.protocol.packet.login.LoginPacket
|
||||
@ -167,8 +168,12 @@ internal class QQAndroidBotNetworkHandler(bot: QQAndroidBot) : BotNetworkHandler
|
||||
coroutineContext = this.coroutineContext,
|
||||
id = it.groupCode,
|
||||
uin = it.groupUin,
|
||||
name = it.groupName,
|
||||
announcement = it.groupMemo,
|
||||
initName = it.groupName,
|
||||
initAnnouncement = it.groupMemo,
|
||||
initAllowMemberInvite = false,
|
||||
initConfessTalk = false,
|
||||
initMuteAll = false,
|
||||
initAutoApprove = false,
|
||||
members = contactList
|
||||
)
|
||||
group.owner =
|
||||
@ -238,6 +243,13 @@ internal class QQAndroidBotNetworkHandler(bot: QQAndroidBot) : BotNetworkHandler
|
||||
MessageSvc.PbGetMsg(bot.client, MsgSvc.SyncFlag.START, currentTimeSeconds).sendWithoutExpect()
|
||||
}
|
||||
|
||||
suspend fun getGroupInfo(uin: Long) {
|
||||
val data = TroopManagement.getGroupInfo(
|
||||
client = bot.client,
|
||||
groupCode = uin
|
||||
).sendAndExpect<TroopManagement.getGroupInfo.Response>(timeoutMillis = 3000)
|
||||
}
|
||||
|
||||
suspend fun getTroopMemberList(group: GroupImpl, list: ContactList<Member>, owner: Long): ContactList<Member> {
|
||||
bot.logger.info("开始获取群[${group.uin}]成员列表")
|
||||
var size = 0
|
||||
|
@ -5,6 +5,266 @@ import kotlinx.serialization.Serializable
|
||||
import net.mamoe.mirai.qqandroid.io.ProtoBuf
|
||||
import net.mamoe.mirai.qqandroid.network.protocol.packet.EMPTY_BYTE_ARRAY
|
||||
|
||||
@Serializable
|
||||
class Oidb0x88d : ProtoBuf {
|
||||
@Serializable
|
||||
class GroupExInfoOnly(
|
||||
@SerialId(1) val tribeId: Int = 0,
|
||||
@SerialId(2) val moneyForAddGroup: Int = 0
|
||||
) : ProtoBuf
|
||||
|
||||
@Serializable
|
||||
class ReqGroupInfo(
|
||||
@SerialId(1) val groupCode: Long = 0L,
|
||||
@SerialId(2) val stgroupinfo: Oidb0x88d.GroupInfo? = null,
|
||||
@SerialId(3) val lastGetGroupNameTime: Int = 0
|
||||
) : ProtoBuf
|
||||
|
||||
@Serializable
|
||||
class RspGroupInfo(
|
||||
@SerialId(1) val groupCode: Long = 0L,
|
||||
@SerialId(2) val result: Int = 0,
|
||||
@SerialId(3) val stgroupinfo: Oidb0x88d.GroupInfo? = null
|
||||
) : ProtoBuf
|
||||
|
||||
@Serializable
|
||||
class GroupGeoInfo(
|
||||
@SerialId(1) val owneruin: Long = 0L,
|
||||
@SerialId(2) val settime: Int = 0,
|
||||
@SerialId(3) val cityid: Int = 0,
|
||||
@SerialId(4) val int64Longitude: Long = 0L,
|
||||
@SerialId(5) val int64Latitude: Long = 0L,
|
||||
@SerialId(6) val geocontent: ByteArray = EMPTY_BYTE_ARRAY,
|
||||
@SerialId(7) val poiId: Long = 0L
|
||||
) : ProtoBuf
|
||||
|
||||
@Serializable
|
||||
class TagRecord(
|
||||
@SerialId(1) val fromUin: Long = 0L,
|
||||
@SerialId(2) val groupCode: Long = 0L,
|
||||
@SerialId(3) val tagId: ByteArray = EMPTY_BYTE_ARRAY,
|
||||
@SerialId(4) val setTime: Long = 0L,
|
||||
@SerialId(5) val goodNum: Int = 0,
|
||||
@SerialId(6) val badNum: Int = 0,
|
||||
@SerialId(7) val tagLen: Int = 0,
|
||||
@SerialId(8) val tagValue: ByteArray = EMPTY_BYTE_ARRAY
|
||||
) : ProtoBuf
|
||||
|
||||
@Serializable
|
||||
class GroupInfo(
|
||||
@SerialId(1) val groupOwner: Long? = null,
|
||||
@SerialId(2) val groupCreateTime: Int? = null,
|
||||
@SerialId(3) val groupFlag: Int? = null,
|
||||
@SerialId(4) val groupFlagExt: Int? = null,
|
||||
@SerialId(5) val groupMemberMaxNum: Int? = null,
|
||||
@SerialId(6) val groupMemberNum: Int? = null,
|
||||
@SerialId(7) val groupOption: Int? = null,
|
||||
@SerialId(8) val groupClassExt: Int? = null,
|
||||
@SerialId(9) val groupSpecialClass: Int? = null,
|
||||
@SerialId(10) val groupLevel: Int? = null,
|
||||
@SerialId(11) val groupFace: Int? = null,
|
||||
@SerialId(12) val groupDefaultPage: Int? = null,
|
||||
@SerialId(13) val groupInfoSeq: Int? = null,
|
||||
@SerialId(14) val groupRoamingTime: Int? = null,
|
||||
@SerialId(15) val ingGroupName: ByteArray? = null,
|
||||
@SerialId(16) val ingGroupMemo: ByteArray? = null,
|
||||
@SerialId(17) val ingGroupFingerMemo: ByteArray? = null,
|
||||
@SerialId(18) val ingGroupClassText: ByteArray? = null,
|
||||
@SerialId(19) val groupAllianceCode: List<Int>? = null,
|
||||
@SerialId(20) val groupExtraAdmNum: Int? = null,
|
||||
@SerialId(21) val groupUin: Long? = null,
|
||||
@SerialId(22) val groupCurMsgSeq: Int? = null,
|
||||
@SerialId(23) val groupLastMsgTime: Int? = null,
|
||||
@SerialId(24) val ingGroupQuestion: ByteArray? = null,
|
||||
@SerialId(25) val ingGroupAnswer: ByteArray? = null,
|
||||
@SerialId(26) val groupVisitorMaxNum: Int? = null,
|
||||
@SerialId(27) val groupVisitorCurNum: Int? = null,
|
||||
@SerialId(28) val levelNameSeq: Int? = null,
|
||||
@SerialId(29) val groupAdminMaxNum: Int? = null,
|
||||
@SerialId(30) val groupAioSkinTimestamp: Int? = null,
|
||||
@SerialId(31) val groupBoardSkinTimestamp: Int? = null,
|
||||
@SerialId(32) val ingGroupAioSkinUrl: ByteArray? = null,
|
||||
@SerialId(33) val ingGroupBoardSkinUrl: ByteArray? = null,
|
||||
@SerialId(34) val groupCoverSkinTimestamp: Int? = null,
|
||||
@SerialId(35) val ingGroupCoverSkinUrl: ByteArray? = null,
|
||||
@SerialId(36) val groupGrade: Int? = null,
|
||||
@SerialId(37) val activeMemberNum: Int? = null,
|
||||
@SerialId(38) val certificationType: Int? = null,
|
||||
@SerialId(39) val ingCertificationText: ByteArray? = null,
|
||||
@SerialId(40) val ingGroupRichFingerMemo: ByteArray? = null,
|
||||
@SerialId(41) val tagRecord: List<TagRecord>? = null,
|
||||
@SerialId(42) val groupGeoInfo: GroupGeoInfo? = null,
|
||||
@SerialId(43) val headPortraitSeq: Int? = null,
|
||||
@SerialId(44) val msgHeadPortrait: GroupHeadPortrait? = null,
|
||||
@SerialId(45) val shutupTimestamp: Int? = null,
|
||||
@SerialId(46) val shutupTimestampMe: Int? = null,
|
||||
@SerialId(47) val createSourceFlag: Int? = null,
|
||||
@SerialId(48) val cmduinMsgSeq: Int? = null,
|
||||
@SerialId(49) val cmduinJoinTime: Int? = null,
|
||||
@SerialId(50) val cmduinUinFlag: Int? = null,
|
||||
@SerialId(51) val cmduinFlagEx: Int? = null,
|
||||
@SerialId(52) val cmduinNewMobileFlag: Int? = null,
|
||||
@SerialId(53) val cmduinReadMsgSeq: Int? = null,
|
||||
@SerialId(54) val cmduinLastMsgTime: Int? = null,
|
||||
@SerialId(55) val groupTypeFlag: Int? = null,
|
||||
@SerialId(56) val appPrivilegeFlag: Int? = null,
|
||||
@SerialId(57) val stGroupExInfo: GroupExInfoOnly? = null,
|
||||
@SerialId(58) val groupSecLevel: Int? = null,
|
||||
@SerialId(59) val groupSecLevelInfo: Int? = null,
|
||||
@SerialId(60) val cmduinPrivilege: Int? = null,
|
||||
@SerialId(61) val ingPoidInfo: ByteArray? = null,
|
||||
@SerialId(62) val cmduinFlagEx2: Int? = null,
|
||||
@SerialId(63) val confUin: Long? = null,
|
||||
@SerialId(64) val confMaxMsgSeq: Int? = null,
|
||||
@SerialId(65) val confToGroupTime: Int? = null,
|
||||
@SerialId(66) val passwordRedbagTime: Int? = null,
|
||||
@SerialId(67) val subscriptionUin: Long? = null,
|
||||
@SerialId(68) val memberListChangeSeq: Int? = null,
|
||||
@SerialId(69) val membercardSeq: Int? = null,
|
||||
@SerialId(70) val rootId: Long? = null,
|
||||
@SerialId(71) val parentId: Long? = null,
|
||||
@SerialId(72) val teamSeq: Int? = null,
|
||||
@SerialId(73) val historyMsgBeginTime: Long? = null,
|
||||
@SerialId(74) val inviteNoAuthNumLimit: Long? = null,
|
||||
@SerialId(75) val cmduinHistoryMsgSeq: Int? = null,
|
||||
@SerialId(76) val cmduinJoinMsgSeq: Int? = null,
|
||||
@SerialId(77) val groupFlagext3: Int? = null,
|
||||
@SerialId(78) val groupOpenAppid: Int? = null,
|
||||
@SerialId(79) val isConfGroup: Int? = null,
|
||||
@SerialId(80) val isModifyConfGroupFace: Int? = null,
|
||||
@SerialId(81) val isModifyConfGroupName: Int? = null,
|
||||
@SerialId(82) val noFingerOpenFlag: Int? = null,
|
||||
@SerialId(83) val noCodeFingerOpenFlag: Int? = null,
|
||||
@SerialId(84) val autoAgreeJoinGroupUserNumForNormalGroup: Int? = null,
|
||||
@SerialId(85) val autoAgreeJoinGroupUserNumForConfGroup: Int? = null,
|
||||
@SerialId(86) val isAllowConfGroupMemberNick: Int? = null,
|
||||
@SerialId(87) val isAllowConfGroupMemberAtAll: Int? = null,
|
||||
@SerialId(88) val isAllowConfGroupMemberModifyGroupName: Int? = null,
|
||||
@SerialId(89) val ingLongGroupName: ByteArray? = null,
|
||||
@SerialId(90) val cmduinJoinRealMsgSeq: Int? = null,
|
||||
@SerialId(91) val isGroupFreeze: Int? = null,
|
||||
@SerialId(92) val msgLimitFrequency: Int? = null,
|
||||
@SerialId(93) val joinGroupAuth: ByteArray? = null,
|
||||
@SerialId(94) val hlGuildAppid: Int? = null,
|
||||
@SerialId(95) val hlGuildSubType: Int? = null,
|
||||
@SerialId(96) val hlGuildOrgid: Int? = null,
|
||||
@SerialId(97) val isAllowHlGuildBinary: Int? = null,
|
||||
@SerialId(98) val cmduinRingtoneId: Int? = null,
|
||||
@SerialId(99) val groupFlagext4: Int? = null,
|
||||
@SerialId(100) val groupFreezeReason: Int? = null
|
||||
) : ProtoBuf
|
||||
|
||||
@Serializable
|
||||
class GroupHeadPortraitInfo(
|
||||
@SerialId(1) val uint32PicId: Int = 0,
|
||||
@SerialId(2) val leftX: Int = 0,
|
||||
@SerialId(3) val leftY: Int = 0,
|
||||
@SerialId(4) val rightX: Int = 0,
|
||||
@SerialId(5) val rightY: Int = 0
|
||||
) : ProtoBuf
|
||||
|
||||
@Serializable
|
||||
class RspBody(
|
||||
@SerialId(1) val stzrspgroupinfo: List<Oidb0x88d.RspGroupInfo>? = null,
|
||||
@SerialId(2) val errorinfo: ByteArray = EMPTY_BYTE_ARRAY
|
||||
) : ProtoBuf
|
||||
|
||||
@Serializable
|
||||
class ReqBody(
|
||||
@SerialId(1) val appid: Int = 0,
|
||||
@SerialId(2) val stzreqgroupinfo: List<Oidb0x88d.ReqGroupInfo>? = null,
|
||||
@SerialId(3) val pcClientVersion: Int = 0
|
||||
) : ProtoBuf
|
||||
|
||||
@Serializable
|
||||
class GroupHeadPortrait(
|
||||
@SerialId(1) val picCnt: Int = 0,
|
||||
@SerialId(2) val msgInfo: List<Oidb0x88d.GroupHeadPortraitInfo>? = null,
|
||||
@SerialId(3) val defaultId: Int = 0,
|
||||
@SerialId(4) val verifyingPicCnt: Int = 0,
|
||||
@SerialId(5) val msgVerifyingpicInfo: List<Oidb0x88d.GroupHeadPortraitInfo>? = null
|
||||
) : ProtoBuf
|
||||
}
|
||||
|
||||
@Serializable
|
||||
class Oidb0x89a : ProtoBuf {
|
||||
@Serializable
|
||||
class GroupNewGuidelinesInfo(
|
||||
@SerialId(1) val boolEnabled: Boolean = false,
|
||||
@SerialId(2) val ingContent: ByteArray = EMPTY_BYTE_ARRAY
|
||||
) : ProtoBuf
|
||||
|
||||
@Serializable
|
||||
class Groupinfo(
|
||||
@SerialId(1) val groupExtAdmNum: Int? = null,
|
||||
@SerialId(2) val flag: Int? = null,
|
||||
@SerialId(3) val ingGroupName: ByteArray? = null,
|
||||
@SerialId(4) val ingGroupMemo: ByteArray? = null,
|
||||
@SerialId(5) val ingGroupFingerMemo: ByteArray? = null,
|
||||
@SerialId(6) val ingGroupAioSkinUrl: ByteArray? = null,
|
||||
@SerialId(7) val ingGroupBoardSkinUrl: ByteArray? = null,
|
||||
@SerialId(8) val ingGroupCoverSkinUrl: ByteArray? = null,
|
||||
@SerialId(9) val groupGrade: Int? = null,
|
||||
@SerialId(10) val activeMemberNum: Int? = null,
|
||||
@SerialId(11) val certificationType: Int? = null,
|
||||
@SerialId(12) val ingCertificationText: ByteArray? = null,
|
||||
@SerialId(13) val ingGroupRichFingerMemo: ByteArray? = null,
|
||||
@SerialId(14) val stGroupNewguidelines: Oidb0x89a.GroupNewGuidelinesInfo? = null,
|
||||
@SerialId(15) val groupFace: Int? = null,
|
||||
@SerialId(16) val addOption: Int? = null,
|
||||
@SerialId(17) val shutupTime: Int? = null,
|
||||
@SerialId(18) val groupTypeFlag: Int? = null,
|
||||
@SerialId(19) val stringGroupTag: List<ByteArray>? = null,
|
||||
@SerialId(20) val msgGroupGeoInfo: Oidb0x89a.GroupGeoInfo? = null,
|
||||
@SerialId(21) val groupClassExt: Int? = null,
|
||||
@SerialId(22) val ingGroupClassText: ByteArray? = null,
|
||||
@SerialId(23) val appPrivilegeFlag: Int? = null,
|
||||
@SerialId(24) val appPrivilegeMask: Int? = null,
|
||||
@SerialId(25) val stGroupExInfo: Oidb0x89a.GroupExInfoOnly? = null,
|
||||
@SerialId(26) val groupSecLevel: Int? = null,
|
||||
@SerialId(27) val groupSecLevelInfo: Int? = null,
|
||||
@SerialId(28) val subscriptionUin: Long? = null,
|
||||
@SerialId(29) val allowMemberInvite: Int? = null,
|
||||
@SerialId(30) val ingGroupQuestion: ByteArray? = null,
|
||||
@SerialId(31) val ingGroupAnswer: ByteArray? = null,
|
||||
@SerialId(32) val groupFlagext3: Int? = null,
|
||||
@SerialId(33) val groupFlagext3Mask: Int? = null,
|
||||
@SerialId(34) val groupOpenAppid: Int? = null,
|
||||
@SerialId(35) val noFingerOpenFlag: Int? = null,
|
||||
@SerialId(36) val noCodeFingerOpenFlag: Int? = null,
|
||||
@SerialId(37) val rootId: Long? = null,
|
||||
@SerialId(38) val msgLimitFrequency: Int? = null
|
||||
) : ProtoBuf
|
||||
|
||||
@Serializable
|
||||
class RspBody(
|
||||
@SerialId(1) val groupCode: Long = 0L,
|
||||
@SerialId(2) val errorinfo: ByteArray = EMPTY_BYTE_ARRAY
|
||||
) : ProtoBuf
|
||||
|
||||
@Serializable
|
||||
class GroupExInfoOnly(
|
||||
@SerialId(1) val tribeId: Int = 0,
|
||||
@SerialId(2) val moneyForAddGroup: Int = 0
|
||||
) : ProtoBuf
|
||||
|
||||
@Serializable
|
||||
class GroupGeoInfo(
|
||||
@SerialId(1) val cityId: Int = 0,
|
||||
@SerialId(2) val longtitude: Long = 0L,
|
||||
@SerialId(3) val latitude: Long = 0L,
|
||||
@SerialId(4) val ingGeoContent: ByteArray = EMPTY_BYTE_ARRAY,
|
||||
@SerialId(5) val poiId: Long = 0L
|
||||
) : ProtoBuf
|
||||
|
||||
@Serializable
|
||||
class ReqBody(
|
||||
@SerialId(1) val groupCode: Long = 0L,
|
||||
@SerialId(2) val stGroupInfo: Oidb0x89a.Groupinfo? = null,
|
||||
@SerialId(3) val originalOperatorUin: Long = 0L,
|
||||
@SerialId(4) val reqGroupOpenAppid: Int = 0
|
||||
) : ProtoBuf
|
||||
}
|
||||
|
||||
@Serializable
|
||||
class Cmd0x7cb : ProtoBuf {
|
||||
|
@ -127,7 +127,8 @@ internal object KnownPacketFactories {
|
||||
LongConn.OffPicDown,
|
||||
TroopManagement.EditNametag,
|
||||
TroopManagement.Mute,
|
||||
TroopManagement.MuteAll
|
||||
TroopManagement.updateGroupInfo,
|
||||
TroopManagement.getGroupInfo
|
||||
)
|
||||
|
||||
object IncomingFactories : List<IncomingPacketFactory<*>> by mutableListOf(
|
||||
|
@ -3,10 +3,14 @@ package net.mamoe.mirai.qqandroid.network.protocol.packet.chat
|
||||
import kotlinx.io.core.ByteReadPacket
|
||||
import kotlinx.io.core.buildPacket
|
||||
import kotlinx.io.core.readBytes
|
||||
import kotlinx.io.core.toByteArray
|
||||
import net.mamoe.mirai.data.Packet
|
||||
import net.mamoe.mirai.qqandroid.QQAndroidBot
|
||||
import net.mamoe.mirai.qqandroid.io.serialization.toByteArray
|
||||
import net.mamoe.mirai.qqandroid.io.serialization.writeProtoBuf
|
||||
import net.mamoe.mirai.qqandroid.network.QQAndroidClient
|
||||
import net.mamoe.mirai.qqandroid.network.protocol.data.proto.Oidb0x88d
|
||||
import net.mamoe.mirai.qqandroid.network.protocol.data.proto.Oidb0x89a
|
||||
import net.mamoe.mirai.qqandroid.network.protocol.data.proto.OidbSso
|
||||
import net.mamoe.mirai.qqandroid.network.protocol.packet.EMPTY_BYTE_ARRAY
|
||||
import net.mamoe.mirai.qqandroid.network.protocol.packet.OutgoingPacket
|
||||
@ -14,6 +18,7 @@ import net.mamoe.mirai.qqandroid.network.protocol.packet.OutgoingPacketFactory
|
||||
import net.mamoe.mirai.qqandroid.network.protocol.packet.buildOutgoingUniPacket
|
||||
import net.mamoe.mirai.qqandroid.network.protocol.packet.login.LoginPacket
|
||||
import net.mamoe.mirai.utils.daysToSeconds
|
||||
import net.mamoe.mirai.utils.io.debugPrintThis
|
||||
|
||||
internal object TroopManagement {
|
||||
|
||||
@ -53,10 +58,9 @@ internal object TroopManagement {
|
||||
}
|
||||
|
||||
|
||||
internal object MuteAll : OutgoingPacketFactory<MuteAll.Response>("OidbSvc.0x89a_0") {
|
||||
override suspend fun ByteReadPacket.decode(bot: QQAndroidBot): Response {
|
||||
return Response
|
||||
}
|
||||
internal object getGroupInfo : OutgoingPacketFactory<getGroupInfo.Response>("OidbSvc.0x88d_7") {
|
||||
|
||||
class Response() : Packet
|
||||
|
||||
operator fun invoke(
|
||||
client: QQAndroidClient,
|
||||
@ -66,18 +70,198 @@ internal object TroopManagement {
|
||||
writeProtoBuf(
|
||||
OidbSso.OIDBSSOPkg.serializer(),
|
||||
OidbSso.OIDBSSOPkg(
|
||||
command = 2202,
|
||||
serviceType = 0,
|
||||
command = 2189,
|
||||
serviceType = 7,
|
||||
result = 0,
|
||||
bodybuffer = EMPTY_BYTE_ARRAY//TODO
|
||||
bodybuffer = Oidb0x88d.ReqBody(
|
||||
appid = 537062845,
|
||||
stzreqgroupinfo = listOf(
|
||||
Oidb0x88d.ReqGroupInfo(
|
||||
stgroupinfo = Oidb0x88d.GroupInfo(
|
||||
groupFlagExt = 0,
|
||||
groupFlagext4 = 0,
|
||||
groupFlag = 0,
|
||||
groupFlagext3 = 0,//获取confess
|
||||
noFingerOpenFlag = 0,
|
||||
cmduinFlagEx2 = 0,
|
||||
groupTypeFlag = 0,
|
||||
appPrivilegeFlag = 0,
|
||||
cmduinFlagEx = 0,
|
||||
cmduinNewMobileFlag = 0,
|
||||
cmduinUinFlag = 0,
|
||||
createSourceFlag = 0,
|
||||
noCodeFingerOpenFlag = 0,
|
||||
ingGroupQuestion = EMPTY_BYTE_ARRAY,
|
||||
ingGroupAnswer = EMPTY_BYTE_ARRAY
|
||||
),
|
||||
groupCode = groupCode
|
||||
)
|
||||
)
|
||||
).toByteArray(Oidb0x88d.ReqBody.serializer())
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun ByteReadPacket.decode(bot: QQAndroidBot): Response {
|
||||
debugPrintThis()
|
||||
return Response()
|
||||
}
|
||||
}
|
||||
|
||||
internal object updateGroupInfo : OutgoingPacketFactory<updateGroupInfo.Response>("OidbSvc.0x89a_0") {
|
||||
override suspend fun ByteReadPacket.decode(bot: QQAndroidBot): Response {
|
||||
return Response
|
||||
}
|
||||
|
||||
fun muteAll(
|
||||
client: QQAndroidClient,
|
||||
groupCode: Long,
|
||||
switch: Boolean
|
||||
): OutgoingPacket {
|
||||
return buildOutgoingUniPacket(client) {
|
||||
writeProtoBuf(
|
||||
OidbSso.OIDBSSOPkg.serializer(),
|
||||
OidbSso.OIDBSSOPkg(
|
||||
command = 2202,
|
||||
bodybuffer = Oidb0x89a.ReqBody(
|
||||
groupCode = groupCode,
|
||||
stGroupInfo = Oidb0x89a.Groupinfo(
|
||||
shutupTime = if (switch) {
|
||||
1
|
||||
} else {
|
||||
0
|
||||
}
|
||||
)
|
||||
).toByteArray(Oidb0x89a.ReqBody.serializer())
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun confessTalk(
|
||||
client: QQAndroidClient,
|
||||
groupCode: Long,
|
||||
switch: Boolean
|
||||
): OutgoingPacket {
|
||||
return buildOutgoingUniPacket(client) {
|
||||
writeProtoBuf(
|
||||
OidbSso.OIDBSSOPkg.serializer(),
|
||||
OidbSso.OIDBSSOPkg(
|
||||
command = 2202,
|
||||
bodybuffer = Oidb0x89a.ReqBody(
|
||||
groupCode = groupCode,
|
||||
stGroupInfo = Oidb0x89a.Groupinfo(
|
||||
groupFlagext3Mask = 8192,
|
||||
groupFlagext3 = if (switch) {
|
||||
0
|
||||
} else {
|
||||
8192
|
||||
}
|
||||
)
|
||||
).toByteArray(Oidb0x89a.ReqBody.serializer())
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun autoApprove(
|
||||
client: QQAndroidClient,
|
||||
groupCode: Long,
|
||||
switch: Boolean
|
||||
): OutgoingPacket {
|
||||
return buildOutgoingUniPacket(client) {
|
||||
writeProtoBuf(
|
||||
OidbSso.OIDBSSOPkg.serializer(),
|
||||
OidbSso.OIDBSSOPkg(
|
||||
command = 2202,
|
||||
bodybuffer = Oidb0x89a.ReqBody(
|
||||
groupCode = groupCode,
|
||||
stGroupInfo = Oidb0x89a.Groupinfo(
|
||||
groupFlagext3 = if (switch) {
|
||||
0x00100000
|
||||
} else {
|
||||
0x00000000
|
||||
}//暂时无效
|
||||
)
|
||||
).toByteArray(Oidb0x89a.ReqBody.serializer())
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun name(
|
||||
client: QQAndroidClient,
|
||||
groupCode: Long,
|
||||
newName: String
|
||||
): OutgoingPacket {
|
||||
return buildOutgoingUniPacket(client) {
|
||||
writeProtoBuf(
|
||||
OidbSso.OIDBSSOPkg.serializer(),
|
||||
OidbSso.OIDBSSOPkg(
|
||||
command = 2202,
|
||||
bodybuffer = Oidb0x89a.ReqBody(
|
||||
groupCode = groupCode,
|
||||
stGroupInfo = Oidb0x89a.Groupinfo(
|
||||
ingGroupName = newName.toByteArray()
|
||||
)
|
||||
).toByteArray(Oidb0x89a.ReqBody.serializer())
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun memo(
|
||||
client: QQAndroidClient,
|
||||
groupCode: Long,
|
||||
newMemo: String
|
||||
): OutgoingPacket {
|
||||
return buildOutgoingUniPacket(client) {
|
||||
writeProtoBuf(
|
||||
OidbSso.OIDBSSOPkg.serializer(),
|
||||
OidbSso.OIDBSSOPkg(
|
||||
command = 2202,
|
||||
bodybuffer = Oidb0x89a.ReqBody(
|
||||
groupCode = groupCode,
|
||||
stGroupInfo = Oidb0x89a.Groupinfo(
|
||||
ingGroupMemo = newMemo.toByteArray()
|
||||
)
|
||||
).toByteArray(Oidb0x89a.ReqBody.serializer())
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun allowMemberInvite(
|
||||
client: QQAndroidClient,
|
||||
groupCode: Long,
|
||||
switch: Boolean
|
||||
): OutgoingPacket {
|
||||
return buildOutgoingUniPacket(client) {
|
||||
writeProtoBuf(
|
||||
OidbSso.OIDBSSOPkg.serializer(),
|
||||
OidbSso.OIDBSSOPkg(
|
||||
command = 2202,
|
||||
bodybuffer = Oidb0x89a.ReqBody(
|
||||
groupCode = groupCode,
|
||||
stGroupInfo = Oidb0x89a.Groupinfo(
|
||||
allowMemberInvite = if (switch) {
|
||||
1
|
||||
} else {
|
||||
0
|
||||
}
|
||||
)
|
||||
).toByteArray(Oidb0x89a.ReqBody.serializer())
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
object Response : Packet
|
||||
}
|
||||
|
||||
|
||||
internal object EditNametag : OutgoingPacketFactory<LoginPacket.LoginPacketResponse>("OidbSvc.0x8fc_2") {
|
||||
override suspend fun ByteReadPacket.decode(bot: QQAndroidBot): LoginPacket.LoginPacketResponse {
|
||||
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
|
||||
|
@ -6,7 +6,7 @@ import java.io.File
|
||||
|
||||
fun main() {
|
||||
println(
|
||||
File("""/Users/jiahua.liu/Desktop/QQAndroid-F/app/src/main/java/tencent/im/s2c/msgtype0x210/submsgtype0xc7/bussinfo/mutualmark""")
|
||||
File("""/Users/jiahua.liu/Desktop/QQAndroid-F/app/src/main/java/tencent/im/oidb/cmd0x88d/""")
|
||||
.generateUnarrangedClasses().toMutableList().arrangeClasses().joinToString("\n\n")
|
||||
)
|
||||
}
|
||||
|
@ -9,6 +9,51 @@ import kotlinx.coroutines.CoroutineScope
|
||||
* 群. 在 QQ Android 中叫做 "Troop"
|
||||
*/
|
||||
interface Group : Contact, CoroutineScope {
|
||||
|
||||
/**
|
||||
* ====以下字段在更新值的时候会自动异步上报服务器更改群信息====
|
||||
*/
|
||||
/**
|
||||
* 群名称
|
||||
* [可查可改已完成]
|
||||
*/
|
||||
var name: String
|
||||
/**
|
||||
* 入群公告, 没有时为空字符串
|
||||
* [可查可改已完成]
|
||||
*/
|
||||
var announcement: String
|
||||
/**
|
||||
* 全体禁言状态
|
||||
* [可改已完成]
|
||||
*/
|
||||
var muteAll: Boolean
|
||||
/**
|
||||
* 坦白说状态
|
||||
* [可查可改已完成]
|
||||
*/
|
||||
var confessTalk: Boolean
|
||||
/**
|
||||
* 允许群员拉人状态
|
||||
* [可查可改已完成]
|
||||
*/
|
||||
var allowMemberInvite: Boolean
|
||||
/**
|
||||
* QQ中的自动加群审批
|
||||
* [可查已完成]
|
||||
*/
|
||||
val autoApprove: Boolean
|
||||
/**
|
||||
* 匿名聊天
|
||||
* [可查已完成]
|
||||
*/
|
||||
val anonymousChat: Boolean
|
||||
|
||||
/**
|
||||
* ====以上字段在更新值的时候会自动异步上报服务器更改群信息====
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* 同为 groupCode, 用户看到的群号码.
|
||||
*/
|
||||
@ -22,22 +67,12 @@ interface Group : Contact, CoroutineScope {
|
||||
|
||||
val botPermission: MemberPermission
|
||||
|
||||
/**
|
||||
* 群名称 (同步事件更新)
|
||||
*/
|
||||
val name: String
|
||||
|
||||
/**
|
||||
* 入群公告, 没有时为空字符串. (同步事件更新)
|
||||
*/
|
||||
val announcement: String
|
||||
|
||||
/**
|
||||
* 在 [Group] 实例创建的时候查询一次. 并与事件同步事件更新
|
||||
*/
|
||||
val members: ContactList<Member>
|
||||
|
||||
|
||||
/**
|
||||
* 获取群成员实例. 若此 id 的成员不存在, 则会抛出 [kotlin.NoSuchElementException]
|
||||
*/
|
||||
@ -58,5 +93,6 @@ interface Group : Contact, CoroutineScope {
|
||||
*/
|
||||
suspend fun quit(): Boolean
|
||||
|
||||
|
||||
fun toFullString(): String = "Group(id=${this.id}, name=$name, owner=${owner.id}, members=${members.idContentString})"
|
||||
}
|
Loading…
Reference in New Issue
Block a user