diff --git a/qqinterface/src/main/java/tencent/im/oidb/cmd0x8a7/cmd0x8a7.java b/qqinterface/src/main/java/tencent/im/oidb/cmd0x8a7/cmd0x8a7.java new file mode 100644 index 0000000..65aa6a0 --- /dev/null +++ b/qqinterface/src/main/java/tencent/im/oidb/cmd0x8a7/cmd0x8a7.java @@ -0,0 +1,51 @@ +package tencent.im.oidb.cmd0x8a7; + +import com.tencent.mobileqq.pb.ByteStringMicro; +import com.tencent.mobileqq.pb.MessageMicro; +import com.tencent.mobileqq.pb.PBBoolField; +import com.tencent.mobileqq.pb.PBBytesField; +import com.tencent.mobileqq.pb.PBField; +import com.tencent.mobileqq.pb.PBUInt32Field; +import com.tencent.mobileqq.pb.PBUInt64Field; + +public class cmd0x8a7 { + public static class ReqBody + extends MessageMicro + { + static final MessageMicro.FieldMap __fieldMap__; + public final PBUInt32Field uint32_limit_interval_type_for_group = PBField.initUInt32(0); + public final PBUInt32Field uint32_limit_interval_type_for_uin = PBField.initUInt32(0); + public final PBUInt32Field uint32_sub_cmd = PBField.initUInt32(0); + public final PBUInt64Field uint64_group_code = PBField.initUInt64(0L); + public final PBUInt64Field uint64_uin = PBField.initUInt64(0L); + + static + { + Integer localInteger = Integer.valueOf(0); + Long localLong = Long.valueOf(0L); + __fieldMap__ = MessageMicro.initFieldMap(new int[] { 8, 16, 24, 32, 40 }, new String[] { "uint32_sub_cmd", "uint32_limit_interval_type_for_uin", "uint32_limit_interval_type_for_group", "uint64_uin", "uint64_group_code" }, new Object[] { localInteger, localInteger, localInteger, localLong, localLong }, ReqBody.class); + } + } + + public static class RspBody + extends MessageMicro + { + static final MessageMicro.FieldMap __fieldMap__; + public final PBBoolField bool_can_at_all = PBField.initBool(false); + public final PBBoolField bool_show_at_all_lable = PBField.initBool(false); + public final PBBytesField bytes_prompt_msg_1 = PBField.initBytes(ByteStringMicro.EMPTY); + public final PBBytesField bytes_prompt_msg_2 = PBField.initBytes(ByteStringMicro.EMPTY); + public final PBUInt32Field uint32_remain_at_all_count_for_group = PBField.initUInt32(0); + public final PBUInt32Field uint32_remain_at_all_count_for_uin = PBField.initUInt32(0); + + static + { + Integer localInteger = Integer.valueOf(0); + Boolean localBoolean = Boolean.valueOf(false); + ByteStringMicro localByteStringMicro1 = ByteStringMicro.EMPTY; + ByteStringMicro localByteStringMicro2 = ByteStringMicro.EMPTY; + __fieldMap__ = MessageMicro.initFieldMap(new int[] { 8, 16, 24, 34, 42, 48 }, new String[] { "bool_can_at_all", "uint32_remain_at_all_count_for_uin", "uint32_remain_at_all_count_for_group", "bytes_prompt_msg_1", "bytes_prompt_msg_2", "bool_show_at_all_lable" }, new Object[] { localBoolean, localInteger, localInteger, localByteStringMicro1, localByteStringMicro2, localBoolean }, RspBody.class); + } + } + +} diff --git a/xposed/src/main/java/moe/fuqiuluo/qqinterface/servlet/GroupSvc.kt b/xposed/src/main/java/moe/fuqiuluo/qqinterface/servlet/GroupSvc.kt index d664660..ee0ab68 100644 --- a/xposed/src/main/java/moe/fuqiuluo/qqinterface/servlet/GroupSvc.kt +++ b/xposed/src/main/java/moe/fuqiuluo/qqinterface/servlet/GroupSvc.kt @@ -47,7 +47,9 @@ import moe.fuqiuluo.proto.ProtoUtils import moe.fuqiuluo.proto.asInt import moe.fuqiuluo.proto.asUtf8String import moe.fuqiuluo.proto.protobufOf +import moe.fuqiuluo.qqinterface.servlet.TicketSvc.getLongUin import moe.fuqiuluo.qqinterface.servlet.TicketSvc.getUin +import moe.fuqiuluo.qqinterface.servlet.entries.GroupAtAllRemainInfo import moe.fuqiuluo.qqinterface.servlet.entries.ProhibitedMemberInfo import moe.fuqiuluo.shamrock.helper.Level import moe.fuqiuluo.shamrock.helper.LogCenter @@ -76,6 +78,7 @@ import tencent.im.group.group_member_info import tencent.im.oidb.cmd0x899.oidb_0x899 import tencent.im.oidb.cmd0x89a.oidb_0x89a import tencent.im.oidb.cmd0x8a0.oidb_0x8a0 +import tencent.im.oidb.cmd0x8a7.cmd0x8a7 import tencent.im.oidb.cmd0x8fc.Oidb_0x8fc import tencent.im.oidb.cmd0xeb7.oidb_0xeb7 import tencent.im.oidb.oidb_sso @@ -102,6 +105,27 @@ internal object GroupSvc: BaseSvc() { private lateinit var METHOD_REQ_TROOP_MEM_LIST: Method private lateinit var METHOD_REQ_MODIFY_GROUP_NAME: Method + suspend fun getGroupRemainAtAllRemain (groupId: Long): Result { + val buffer = sendOidbAW("OidbSvcTrpcTcp.0x8a7_0", 2215, 0, cmd0x8a7.ReqBody().apply { + uint32_sub_cmd.set(1) + uint32_limit_interval_type_for_uin.set(2) + uint32_limit_interval_type_for_group.set(1) + uint64_uin.set(getLongUin()) + uint64_group_code.set(groupId) + }.toByteArray(), trpc = true) ?: return Result.failure(RuntimeException("[oidb] timeout")) + val body = oidb_sso.OIDBSSOPkg() + body.mergeFrom(buffer.slice(4)) + if(body.uint32_result.get() != 0) { + return Result.failure(RuntimeException(body.str_error_msg.get())) + } + + val resp = cmd0x8a7.RspBody().mergeFrom(body.bytes_bodybuffer.get().toByteArray()) + return Result.success(GroupAtAllRemainInfo( + canAtAll = resp.bool_can_at_all.get(), + remainAtAllCountForGroup = resp.uint32_remain_at_all_count_for_group.get(), + remainAtAllCountForUin = resp.uint32_remain_at_all_count_for_uin.get() + )) + } suspend fun getProhibitedMemberList(groupId: Long): Result> { val buffer = sendOidbAW("OidbSvc.0x899_0", 2201, 0, oidb_0x899.ReqBody().apply { uint64_group_code.set(groupId) diff --git a/xposed/src/main/java/moe/fuqiuluo/qqinterface/servlet/entries/GroupEntries.kt b/xposed/src/main/java/moe/fuqiuluo/qqinterface/servlet/entries/GroupEntries.kt index f03fd56..4ce1a6a 100644 --- a/xposed/src/main/java/moe/fuqiuluo/qqinterface/servlet/entries/GroupEntries.kt +++ b/xposed/src/main/java/moe/fuqiuluo/qqinterface/servlet/entries/GroupEntries.kt @@ -7,4 +7,11 @@ import kotlinx.serialization.Serializable internal data class ProhibitedMemberInfo( @SerialName("user_id") val memberUin: Long, @SerialName("time") val shutuptimestap: Int +) + +@Serializable +internal data class GroupAtAllRemainInfo( + @SerialName("can_at_all") val canAtAll: Boolean, + @SerialName("remain_at_all_count_for_group") val remainAtAllCountForGroup: Int, + @SerialName("remain_at_all_count_for_uin") val remainAtAllCountForUin: Int ) \ No newline at end of file diff --git a/xposed/src/main/java/moe/fuqiuluo/shamrock/remote/action/ActionManager.kt b/xposed/src/main/java/moe/fuqiuluo/shamrock/remote/action/ActionManager.kt index a7f51d4..97a087a 100644 --- a/xposed/src/main/java/moe/fuqiuluo/shamrock/remote/action/ActionManager.kt +++ b/xposed/src/main/java/moe/fuqiuluo/shamrock/remote/action/ActionManager.kt @@ -32,6 +32,7 @@ internal object ActionManager { ModifyTroopName, LeaveTroop, KickTroopMember, BanTroopMember, SetGroupWholeBan, SetGroupAdmin, ModifyTroopMemberName, SetGroupUnique, GetTroopHonor, GroupPoke, SetEssenceMessage, DeleteEssenceMessage, GetGroupSystemMsg, GetProhibitedMemberList, GetEssenceMessageList, GetGroupNotice, SendGroupNotice, SendGroupSign, + GetGroupRemainAtAllRemain, // MSG ACTIONS SendMessage, DeleteMessage, GetMsg, GetForwardMsg, SendPrivateForwardMessage, SendGroupMessage, SendPrivateMessage, diff --git a/xposed/src/main/java/moe/fuqiuluo/shamrock/remote/action/handlers/GetGroupRemainAtAllRemain.kt b/xposed/src/main/java/moe/fuqiuluo/shamrock/remote/action/handlers/GetGroupRemainAtAllRemain.kt new file mode 100644 index 0000000..ea1389f --- /dev/null +++ b/xposed/src/main/java/moe/fuqiuluo/shamrock/remote/action/handlers/GetGroupRemainAtAllRemain.kt @@ -0,0 +1,29 @@ +package moe.fuqiuluo.shamrock.remote.action.handlers + +import kotlinx.serialization.json.JsonElement +import moe.fuqiuluo.qqinterface.servlet.GroupSvc +import moe.fuqiuluo.shamrock.remote.action.ActionSession +import moe.fuqiuluo.shamrock.remote.action.IActionHandler +import moe.fuqiuluo.shamrock.tools.EmptyJsonString + +internal object GetGroupRemainAtAllRemain: IActionHandler() { + override suspend fun internalHandle(session: ActionSession): String { + val groupId = session.getLong("group_id") + return invoke(groupId, session.echo) + } + + suspend operator fun invoke( + groupId: Long, + echo: JsonElement = EmptyJsonString + ): String { + val result = GroupSvc.getGroupRemainAtAllRemain(groupId) + if (result.isFailure) { + return error(result.exceptionOrNull()?.message ?: "获取群 @全体成员 剩余次数失败", echo, arrayResult = true) + } + return ok(result.getOrThrow(), echo) + } + + override val requiredParams: Array = arrayOf("group_id") + + override fun path(): String = "get_group_at_all_remain" +} \ No newline at end of file diff --git a/xposed/src/main/java/moe/fuqiuluo/shamrock/remote/api/GroupAction.kt b/xposed/src/main/java/moe/fuqiuluo/shamrock/remote/api/GroupAction.kt index b2fa491..d393260 100644 --- a/xposed/src/main/java/moe/fuqiuluo/shamrock/remote/api/GroupAction.kt +++ b/xposed/src/main/java/moe/fuqiuluo/shamrock/remote/api/GroupAction.kt @@ -145,4 +145,9 @@ fun Routing.troopAction() { call.respondText(SendGroupSign(groupId), ContentType.Application.Json) } + getOrPost("/get_group_at_all_remain") { + val groupId = fetchOrThrow("group_id").toLong() + call.respondText(GetGroupRemainAtAllRemain(groupId), ContentType.Application.Json) + } + } \ No newline at end of file