From 16f77de5a62d93af97870189ab17fc0afd7af55f Mon Sep 17 00:00:00 2001 From: ikechan8370 Date: Mon, 20 Nov 2023 18:36:46 +0800 Subject: [PATCH] =?UTF-8?q?Shamrock:=20feat:=20=E7=B2=BE=E5=8D=8E=E6=B6=88?= =?UTF-8?q?=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../fuqiuluo/qqinterface/servlet/GroupSvc.kt | 49 +++++++++++++++++++ .../shamrock/remote/action/ActionManager.kt | 2 +- .../action/handlers/DeleteEssenceMessage.kt | 34 +++++++++++++ .../shamrock/remote/action/handlers/GetMsg.kt | 2 +- .../action/handlers/SetEssenceMessage.kt | 35 +++++++++++++ .../shamrock/remote/api/GroupAction.kt | 11 +++++ 6 files changed, 131 insertions(+), 2 deletions(-) create mode 100644 xposed/src/main/java/moe/fuqiuluo/shamrock/remote/action/handlers/DeleteEssenceMessage.kt create mode 100644 xposed/src/main/java/moe/fuqiuluo/shamrock/remote/action/handlers/SetEssenceMessage.kt 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 ccef6ee..4809a90 100644 --- a/xposed/src/main/java/moe/fuqiuluo/qqinterface/servlet/GroupSvc.kt +++ b/xposed/src/main/java/moe/fuqiuluo/qqinterface/servlet/GroupSvc.kt @@ -22,7 +22,10 @@ import kotlinx.coroutines.suspendCancellableCoroutine import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.withLock import kotlinx.coroutines.withTimeoutOrNull +import moe.fuqiuluo.proto.ProtoUtils +import moe.fuqiuluo.proto.asUtf8String import moe.fuqiuluo.proto.protobufOf +import moe.fuqiuluo.shamrock.helper.LogCenter import moe.fuqiuluo.shamrock.tools.ifNullOrEmpty import moe.fuqiuluo.shamrock.tools.putBuf32Long import moe.fuqiuluo.shamrock.tools.slice @@ -32,6 +35,7 @@ import mqq.app.MobileQQ import tencent.im.oidb.cmd0x89a.oidb_0x89a import tencent.im.oidb.cmd0x8a0.oidb_0x8a0 import tencent.im.oidb.cmd0x8fc.Oidb_0x8fc +import tencent.im.oidb.oidb_sso import java.lang.reflect.Method import java.lang.reflect.Modifier import java.nio.ByteBuffer @@ -139,6 +143,51 @@ internal object GroupSvc: BaseSvc() { return true } + suspend fun setEssenceMessage(groupId: Long, seq: Long, rand: Long): Pair { + val array = protobufOf( + 1 to groupId, + 2 to seq, + 3 to rand + ).toByteArray() + val buffer = sendOidbAW("OidbSvc.0xeac_1", 3756, 1, array) + val body = oidb_sso.OIDBSSOPkg() + if (buffer == null) { + return Pair(false, "unknown error") + } + body.mergeFrom(buffer.slice(4)) + val result = ProtoUtils.decodeFromByteArray(body.bytes_bodybuffer.get().toByteArray()) + return if (result.has(1)) { + LogCenter.log("设置群精华失败: ${result[1].asUtf8String}") + Pair(false, "设置群精华失败: ${result[1].asUtf8String}") + } else { + LogCenter.log("设置群精华 -> $groupId:$seq") + Pair(true, "ok") + } + } + + suspend fun deleteEssenceMessage(groupId: Long, seq: Long, rand: Long): Pair { + val array = protobufOf( + 1 to groupId, + 2 to seq, + 3 to rand + ).toByteArray() + val buffer = sendOidbAW("OidbSvc.0xeac_2", 3756, 2, array) + val body = oidb_sso.OIDBSSOPkg() + if (buffer == null) { + return Pair(false, "unknown error") + } + body.mergeFrom(buffer.slice(4)) + val result = ProtoUtils.decodeFromByteArray(body.bytes_bodybuffer.get().toByteArray()) + return if (result.has(1)) { + LogCenter.log("移除群精华失败: ${result[1].asUtf8String}") + Pair(false, "移除群精华失败: ${result[1].asUtf8String}") + } else { + LogCenter.log("移除群精华 -> $groupId:$seq") + Pair(true, "ok") + } + + } + fun setGroupAdmin(groupId: Long, userId: Long, enable: Boolean) { val buffer = ByteBuffer.allocate(9) buffer.putBuf32Long(groupId) 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 a110a29..6af2636 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 @@ -29,7 +29,7 @@ internal object ActionManager { // GroupActions ModifyTroopName, LeaveTroop, KickTroopMember, BanTroopMember, SetGroupWholeBan, SetGroupAdmin, - ModifyTroopMemberName, SetGroupUnique, GetTroopHonor, GroupPoke, + ModifyTroopMemberName, SetGroupUnique, GetTroopHonor, GroupPoke, SetEssenceMessage, DeleteEssenceMessage, // MSG ACTIONS SendMessage, DeleteMessage, GetMsg, GetForwardMsg, SendGroupForwardMsg, SendGroupMessage, SendPrivateMessage, diff --git a/xposed/src/main/java/moe/fuqiuluo/shamrock/remote/action/handlers/DeleteEssenceMessage.kt b/xposed/src/main/java/moe/fuqiuluo/shamrock/remote/action/handlers/DeleteEssenceMessage.kt new file mode 100644 index 0000000..db20280 --- /dev/null +++ b/xposed/src/main/java/moe/fuqiuluo/shamrock/remote/action/handlers/DeleteEssenceMessage.kt @@ -0,0 +1,34 @@ +package moe.fuqiuluo.shamrock.remote.action.handlers + +import com.tencent.qqnt.kernel.nativeinterface.MsgConstant +import kotlinx.serialization.json.JsonElement +import moe.fuqiuluo.qqinterface.servlet.GroupSvc +import moe.fuqiuluo.qqinterface.servlet.MsgSvc +import moe.fuqiuluo.shamrock.remote.action.ActionSession +import moe.fuqiuluo.shamrock.remote.action.IActionHandler +import moe.fuqiuluo.shamrock.tools.EmptyJsonString + +internal object DeleteEssenceMessage: IActionHandler() { + override suspend fun internalHandle(session: ActionSession): String { + val messageId = session.getInt("message_id") + return invoke(messageId, session.echo) + } + + suspend operator fun invoke(messageId: Int, echo: JsonElement = EmptyJsonString): String { + val msg = MsgSvc.getMsg(messageId).onFailure { + return logic("Obtain msg failed, please check your msg_id.", echo) + }.getOrThrow() + val (success, tip) = GroupSvc.deleteEssenceMessage( + if (msg.chatType == MsgConstant.KCHATTYPEGROUP) msg.peerUin else 0, + msg.msgSeq, + msg.msgRandom + ) + return if (success) { + ok("成功", echo) + } else { + logic(tip, echo) + } + } + + override fun path(): String = "delete_essence_message" +} \ No newline at end of file diff --git a/xposed/src/main/java/moe/fuqiuluo/shamrock/remote/action/handlers/GetMsg.kt b/xposed/src/main/java/moe/fuqiuluo/shamrock/remote/action/handlers/GetMsg.kt index b6dcfce..f52cac5 100644 --- a/xposed/src/main/java/moe/fuqiuluo/shamrock/remote/action/handlers/GetMsg.kt +++ b/xposed/src/main/java/moe/fuqiuluo/shamrock/remote/action/handlers/GetMsg.kt @@ -22,7 +22,7 @@ internal object GetMsg: IActionHandler() { val msg = MsgSvc.getMsg(msgHash).onFailure { return logic("Obtain msg failed, please check your msg_id.", echo) }.getOrThrow() - val seq = msg.clientSeq.toInt() + val seq = msg.msgSeq.toInt() return ok(MessageDetail( time = msg.msgTime.toInt(), msgType = MessageHelper.obtainDetailTypeByMsgType(msg.chatType), diff --git a/xposed/src/main/java/moe/fuqiuluo/shamrock/remote/action/handlers/SetEssenceMessage.kt b/xposed/src/main/java/moe/fuqiuluo/shamrock/remote/action/handlers/SetEssenceMessage.kt new file mode 100644 index 0000000..aa09550 --- /dev/null +++ b/xposed/src/main/java/moe/fuqiuluo/shamrock/remote/action/handlers/SetEssenceMessage.kt @@ -0,0 +1,35 @@ +package moe.fuqiuluo.shamrock.remote.action.handlers + +import com.tencent.qqnt.kernel.nativeinterface.MsgConstant +import kotlinx.serialization.json.JsonElement +import moe.fuqiuluo.qqinterface.servlet.GroupSvc +import moe.fuqiuluo.qqinterface.servlet.MsgSvc +import moe.fuqiuluo.shamrock.remote.action.ActionSession +import moe.fuqiuluo.shamrock.remote.action.IActionHandler +import moe.fuqiuluo.shamrock.tools.EmptyJsonString + +internal object SetEssenceMessage: IActionHandler() { + override suspend fun internalHandle(session: ActionSession): String { + val messageId = session.getInt("message_id") + return invoke(messageId, session.echo) + } + + suspend operator fun invoke(messageId: Int, echo: JsonElement = EmptyJsonString): String { + val msg = MsgSvc.getMsg(messageId).onFailure { + return logic("Obtain msg failed, please check your msg_id.", echo) + }.getOrThrow() + val (success, tip) = GroupSvc.setEssenceMessage( + if (msg.chatType == MsgConstant.KCHATTYPEGROUP) msg.peerUin else 0, + msg.msgSeq, + msg.msgRandom + ) + return if (success) { + ok("成功", echo) + } else { + logic(tip, echo) + } + + } + + override fun path(): String = "set_essence_message" +} \ 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 1e6ea89..ac2e039 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 @@ -95,4 +95,15 @@ fun Routing.troopAction() { val groupId = fetchOrThrow("group_id").toLong() call.respondText(KickTroopMember(groupId, userId), ContentType.Application.Json) } + + getOrPost("/set_essence_msg") { + val messageId = fetchOrThrow("message_id").toInt() + call.respondText(SetEssenceMessage(messageId), ContentType.Application.Json) + } + + getOrPost("/delete_essence_msg") { + val messageId = fetchOrThrow("message_id").toInt() + call.respondText(DeleteEssenceMessage(messageId), ContentType.Application.Json) + } + } \ No newline at end of file