From 675a7a5321ee82d6e0bdfa6b19ead6a24e5e3635 Mon Sep 17 00:00:00 2001 From: Simplxs Date: Sun, 25 Feb 2024 16:48:31 +0800 Subject: [PATCH] refactor InlineKeyboard --- .../nativeinterface/InlineKeyboardButton.java | 37 +++++++++-- .../kernel/nativeinterface/MsgRecord.java | 12 +++- .../servlet/msg/converter/ElemConverter.kt | 49 ++++++++------- .../msg/converter/NtMsgElementConverter.kt | 62 +++++++++---------- .../servlet/msg/maker/ElemMaker.kt | 1 - .../servlet/msg/maker/NtMsgElementMaker.kt | 57 +++++++++-------- .../shamrock/remote/api/TestAction.kt | 1 + 7 files changed, 128 insertions(+), 91 deletions(-) diff --git a/qqinterface/src/main/java/com/tencent/qqnt/kernel/nativeinterface/InlineKeyboardButton.java b/qqinterface/src/main/java/com/tencent/qqnt/kernel/nativeinterface/InlineKeyboardButton.java index 9fe2222c..a40b114b 100644 --- a/qqinterface/src/main/java/com/tencent/qqnt/kernel/nativeinterface/InlineKeyboardButton.java +++ b/qqinterface/src/main/java/com/tencent/qqnt/kernel/nativeinterface/InlineKeyboardButton.java @@ -2,17 +2,20 @@ import java.util.ArrayList; - -public final class InlineKeyboardButton { +public final class InlineKeyboardButton { + int anchor; boolean atBotShowChannelList; int clickLimit; String data; + boolean enter; String id; + boolean isReply; String label; int permissionType; ArrayList specifyRoleIds; ArrayList specifyTinyids; int style; + ArrayList subscribeDataTemplateIds; int type; String unsupportTips; String visitedLabel; @@ -25,6 +28,11 @@ public InlineKeyboardButton() { this.data = ""; this.specifyRoleIds = new ArrayList<>(); this.specifyTinyids = new ArrayList<>(); + this.subscribeDataTemplateIds = new ArrayList<>(); + } + + public int getAnchor() { + return this.anchor; } public boolean getAtBotShowChannelList() { @@ -39,10 +47,18 @@ public String getData() { return this.data; } + public boolean getEnter() { + return this.enter; + } + public String getId() { return this.id; } + public boolean getIsReply() { + return this.isReply; + } + public String getLabel() { return this.label; } @@ -63,6 +79,10 @@ public int getStyle() { return this.style; } + public ArrayList getSubscribeDataTemplateIds() { + return this.subscribeDataTemplateIds; + } + public int getType() { return this.type; } @@ -76,14 +96,14 @@ public String getVisitedLabel() { } public String toString() { - return "InlineKeyboardButton{id=" + this.id + ",label=" + this.label + ",visitedLabel=" + this.visitedLabel + ",style=" + this.style + ",type=" + this.type + ",clickLimit=" + this.clickLimit + ",unsupportTips=" + this.unsupportTips + ",data=" + this.data + ",atBotShowChannelList=" + this.atBotShowChannelList + ",permissionType=" + this.permissionType + ",specifyRoleIds=" + this.specifyRoleIds + ",specifyTinyids=" + this.specifyTinyids + ",}"; + return "InlineKeyboardButton{id=" + this.id + ",label=" + this.label + ",visitedLabel=" + this.visitedLabel + ",style=" + this.style + ",type=" + this.type + ",clickLimit=" + this.clickLimit + ",unsupportTips=" + this.unsupportTips + ",data=" + this.data + ",atBotShowChannelList=" + this.atBotShowChannelList + ",permissionType=" + this.permissionType + ",specifyRoleIds=" + this.specifyRoleIds + ",specifyTinyids=" + this.specifyTinyids + ",isReply=" + this.isReply + ",anchor=" + this.anchor + ",enter=" + this.enter + ",subscribeDataTemplateIds=" + this.subscribeDataTemplateIds + ",}"; } - public InlineKeyboardButton(String str, String str2, String str3, int i, int i2, int i3, String str4, String str5, boolean z, int i4, ArrayList arrayList, ArrayList arrayList2, boolean z2, int i5, boolean z3, ArrayList arrayList3) { + public InlineKeyboardButton(String str, String str2, String str3, int i, int i2, int i3, String str4, String str5, boolean z, int i4, ArrayList arrayList, ArrayList arrayList2) { } - public InlineKeyboardButton(String str, String str2, String str3, int i2, int i3, int i4, String str4, String str5, boolean z, int i5, ArrayList arrayList, ArrayList arrayList2) { + public InlineKeyboardButton(String str, String str2, String str3, int i2, int i3, int i4, String str4, String str5, boolean z, int i5, ArrayList arrayList, ArrayList arrayList2, boolean z2, int i6, boolean z3, ArrayList arrayList3) { this.id = ""; this.label = ""; this.visitedLabel = ""; @@ -91,6 +111,7 @@ public InlineKeyboardButton(String str, String str2, String str3, int i2, int i3 this.data = ""; this.specifyRoleIds = new ArrayList<>(); this.specifyTinyids = new ArrayList<>(); + this.subscribeDataTemplateIds = new ArrayList<>(); this.id = str; this.label = str2; this.visitedLabel = str3; @@ -103,5 +124,9 @@ public InlineKeyboardButton(String str, String str2, String str3, int i2, int i3 this.permissionType = i5; this.specifyRoleIds = arrayList; this.specifyTinyids = arrayList2; + this.isReply = z2; + this.anchor = i6; + this.enter = z3; + this.subscribeDataTemplateIds = arrayList3; } -} +} \ No newline at end of file diff --git a/qqinterface/src/main/java/com/tencent/qqnt/kernel/nativeinterface/MsgRecord.java b/qqinterface/src/main/java/com/tencent/qqnt/kernel/nativeinterface/MsgRecord.java index f3fda7b3..a5604d74 100644 --- a/qqinterface/src/main/java/com/tencent/qqnt/kernel/nativeinterface/MsgRecord.java +++ b/qqinterface/src/main/java/com/tencent/qqnt/kernel/nativeinterface/MsgRecord.java @@ -39,6 +39,7 @@ public class MsgRecord { boolean isOnlineMsg; FromRoleInfo levelRoleInfo; HashMap msgAttrs; + byte[] msgEventInfo; long msgId; byte[] msgMeta; long msgRandom; @@ -231,6 +232,10 @@ public HashMap getMsgAttrs() { return this.msgAttrs; } + public byte[] getMsgEventInfo() { + return this.msgEventInfo; + } + public long getMsgId() { return this.msgId; } @@ -332,10 +337,10 @@ public long getTimeStamp() { } public String toString() { - return "MsgRecord{msgId=" + this.msgId + ",msgRandom=" + this.msgRandom + ",msgSeq=" + this.msgSeq + ",cntSeq=" + this.cntSeq + ",chatType=" + this.chatType + ",msgType=" + this.msgType + ",subMsgType=" + this.subMsgType + ",sendType=" + this.sendType + ",senderUid=" + this.senderUid + ",peerUid=" + this.peerUid + ",channelId=" + this.channelId + ",guildId=" + this.guildId + ",guildCode=" + this.guildCode + ",fromUid=" + this.fromUid + ",fromAppid=" + this.fromAppid + ",msgTime=" + this.msgTime + ",msgMeta=" + this.msgMeta + ",sendStatus=" + this.sendStatus + ",sendRemarkName=" + this.sendRemarkName + ",sendMemberName=" + this.sendMemberName + ",sendNickName=" + this.sendNickName + ",guildName=" + this.guildName + ",channelName=" + this.channelName + ",elements=" + this.elements + ",records=" + this.records + ",emojiLikesList=" + this.emojiLikesList + ",commentCnt=" + this.commentCnt + ",directMsgFlag=" + this.directMsgFlag + ",directMsgMembers=" + this.directMsgMembers + ",peerName=" + this.peerName + ",freqLimitInfo=" + this.freqLimitInfo + ",editable=" + this.editable + ",avatarMeta=" + this.avatarMeta + ",avatarPendant=" + this.avatarPendant + ",feedId=" + this.feedId + ",roleId=" + this.roleId + ",timeStamp=" + this.timeStamp + ",clientIdentityInfo=" + this.clientIdentityInfo + ",isImportMsg=" + this.isImportMsg + ",atType=" + this.atType + ",roleType=" + this.roleType + ",fromChannelRoleInfo=" + this.fromChannelRoleInfo + ",fromGuildRoleInfo=" + this.fromGuildRoleInfo + ",levelRoleInfo=" + this.levelRoleInfo + ",recallTime=" + this.recallTime + ",isOnlineMsg=" + this.isOnlineMsg + ",generalFlags=" + this.generalFlags + ",clientSeq=" + this.clientSeq + ",fileGroupSize=" + this.fileGroupSize + ",foldingInfo=" + this.foldingInfo + ",multiTransInfo=" + this.multiTransInfo + ",senderUin=" + this.senderUin + ",peerUin=" + this.peerUin + ",msgAttrs=" + this.msgAttrs + ",anonymousExtInfo=" + this.anonymousExtInfo + ",nameType=" + this.nameType + ",avatarFlag=" + this.avatarFlag + ",extInfoForUI=" + this.extInfoForUI + ",personalMedal=" + this.personalMedal + ",categoryManage=" + this.categoryManage + ",}"; + return "MsgRecord{msgId=" + this.msgId + ",msgRandom=" + this.msgRandom + ",msgSeq=" + this.msgSeq + ",cntSeq=" + this.cntSeq + ",chatType=" + this.chatType + ",msgType=" + this.msgType + ",subMsgType=" + this.subMsgType + ",sendType=" + this.sendType + ",senderUid=" + this.senderUid + ",peerUid=" + this.peerUid + ",channelId=" + this.channelId + ",guildId=" + this.guildId + ",guildCode=" + this.guildCode + ",fromUid=" + this.fromUid + ",fromAppid=" + this.fromAppid + ",msgTime=" + this.msgTime + ",msgMeta=" + this.msgMeta + ",sendStatus=" + this.sendStatus + ",sendRemarkName=" + this.sendRemarkName + ",sendMemberName=" + this.sendMemberName + ",sendNickName=" + this.sendNickName + ",guildName=" + this.guildName + ",channelName=" + this.channelName + ",elements=" + this.elements + ",records=" + this.records + ",emojiLikesList=" + this.emojiLikesList + ",commentCnt=" + this.commentCnt + ",directMsgFlag=" + this.directMsgFlag + ",directMsgMembers=" + this.directMsgMembers + ",peerName=" + this.peerName + ",freqLimitInfo=" + this.freqLimitInfo + ",editable=" + this.editable + ",avatarMeta=" + this.avatarMeta + ",avatarPendant=" + this.avatarPendant + ",feedId=" + this.feedId + ",roleId=" + this.roleId + ",timeStamp=" + this.timeStamp + ",clientIdentityInfo=" + this.clientIdentityInfo + ",isImportMsg=" + this.isImportMsg + ",atType=" + this.atType + ",roleType=" + this.roleType + ",fromChannelRoleInfo=" + this.fromChannelRoleInfo + ",fromGuildRoleInfo=" + this.fromGuildRoleInfo + ",levelRoleInfo=" + this.levelRoleInfo + ",recallTime=" + this.recallTime + ",isOnlineMsg=" + this.isOnlineMsg + ",generalFlags=" + this.generalFlags + ",clientSeq=" + this.clientSeq + ",fileGroupSize=" + this.fileGroupSize + ",foldingInfo=" + this.foldingInfo + ",multiTransInfo=" + this.multiTransInfo + ",senderUin=" + this.senderUin + ",peerUin=" + this.peerUin + ",msgAttrs=" + this.msgAttrs + ",anonymousExtInfo=" + this.anonymousExtInfo + ",nameType=" + this.nameType + ",avatarFlag=" + this.avatarFlag + ",extInfoForUI=" + this.extInfoForUI + ",personalMedal=" + this.personalMedal + ",categoryManage=" + this.categoryManage + ",msgEventInfo=" + this.msgEventInfo + ",}"; } - public MsgRecord(long j2, long j3, long j4, long j5, int i2, int i3, int i4, int i5, String str, String str2, String str3, String str4, long j6, long j7, long j8, long j9, byte[] bArr, int i6, String str5, String str6, String str7, String str8, String str9, ArrayList arrayList, ArrayList arrayList2, ArrayList arrayList3, long j10, int i7, ArrayList arrayList4, String str10, FreqLimitInfo freqLimitInfo, boolean z, String str11, String str12, String str13, long j11, long j12, GProClientIdentity gProClientIdentity, boolean z2, int i8, int i9, FromRoleInfo fromRoleInfo, FromRoleInfo fromRoleInfo2, FromRoleInfo fromRoleInfo3, long j13, boolean z3, byte[] bArr2, long j14, Integer num, FoldingInfo foldingInfo, MultiTransInfo multiTransInfo, long j15, long j16, HashMap hashMap, AnonymousExtInfo anonymousExtInfo, int i10, int i11, byte[] bArr3, GProMedal gProMedal, int i12) { + public MsgRecord(long j2, long j3, long j4, long j5, int i2, int i3, int i4, int i5, String str, String str2, String str3, String str4, long j6, long j7, long j8, long j9, byte[] bArr, int i6, String str5, String str6, String str7, String str8, String str9, ArrayList arrayList, ArrayList arrayList2, ArrayList arrayList3, long j10, int i7, ArrayList arrayList4, String str10, FreqLimitInfo freqLimitInfo, boolean z, String str11, String str12, String str13, long j11, long j12, GProClientIdentity gProClientIdentity, boolean z2, int i8, int i9, FromRoleInfo fromRoleInfo, FromRoleInfo fromRoleInfo2, FromRoleInfo fromRoleInfo3, long j13, boolean z3, byte[] bArr2, long j14, Integer num, FoldingInfo foldingInfo, MultiTransInfo multiTransInfo, long j15, long j16, HashMap hashMap, AnonymousExtInfo anonymousExtInfo, int i10, int i11, byte[] bArr3, GProMedal gProMedal, int i12, byte[] bArr4) { this.senderUid = ""; this.peerUid = ""; this.channelId = ""; @@ -419,5 +424,6 @@ public MsgRecord(long j2, long j3, long j4, long j5, int i2, int i3, int i4, int this.extInfoForUI = bArr3; this.personalMedal = gProMedal; this.categoryManage = i12; + this.msgEventInfo = bArr4; } -} +} \ No newline at end of file diff --git a/xposed/src/main/java/moe/fuqiuluo/qqinterface/servlet/msg/converter/ElemConverter.kt b/xposed/src/main/java/moe/fuqiuluo/qqinterface/servlet/msg/converter/ElemConverter.kt index be31b4d1..60ae7a44 100644 --- a/xposed/src/main/java/moe/fuqiuluo/qqinterface/servlet/msg/converter/ElemConverter.kt +++ b/xposed/src/main/java/moe/fuqiuluo/qqinterface/servlet/msg/converter/ElemConverter.kt @@ -449,32 +449,33 @@ internal object ElemConverter { type = "button", data = buttonExtra.field1!!.let { mapOf( - "buttons" to it.rows!!.map { row -> - row.buttons!!.map { button -> - val renderData = button.renderData - val action = button.action - val permission = action?.permission - mapOf( - "id" to button.id, - "render_data" to mapOf( - "label" to (renderData?.label ?: ""), - "visited_label" to (renderData?.visitedLabel ?: ""), - "style" to (renderData?.style ?: 0) - ), - "action" to mapOf( - "type" to (action?.type ?: 0), - "permission" to mapOf( - "type" to (permission?.type ?: 0), - "specify_role_ids" to permission?.specifyRoleIds, - "specify_user_ids" to permission?.specifyUserIds + "rows" to it.rows!!.map { row -> + mapOf( + "buttons" to row.buttons!!.map { button -> + val renderData = button.renderData + val action = button.action + val permission = action?.permission + mapOf( + "id" to button.id, + "render_data" to mapOf( + "label" to (renderData?.label ?: ""), + "visited_label" to (renderData?.visitedLabel ?: ""), + "style" to (renderData?.style ?: 0) ), - "unsupport_tips" to (action?.unsupportTips ?: ""), - "data" to (action?.data ?: ""), - "reply" to action?.reply, - "enter" to action?.enter, + "action" to mapOf( + "type" to (action?.type ?: 0), + "permission" to mapOf( + "type" to (permission?.type ?: 0), + "specify_role_ids" to permission?.specifyRoleIds, + "specify_user_ids" to permission?.specifyUserIds + ), + "unsupport_tips" to (action?.unsupportTips ?: ""), + "data" to (action?.data ?: ""), + "reply" to action?.reply, + "enter" to action?.enter, + ) ) - ) - } + }) }, "appid" to it.appid ) diff --git a/xposed/src/main/java/moe/fuqiuluo/qqinterface/servlet/msg/converter/NtMsgElementConverter.kt b/xposed/src/main/java/moe/fuqiuluo/qqinterface/servlet/msg/converter/NtMsgElementConverter.kt index a050e9d8..4562c152 100644 --- a/xposed/src/main/java/moe/fuqiuluo/qqinterface/servlet/msg/converter/NtMsgElementConverter.kt +++ b/xposed/src/main/java/moe/fuqiuluo/qqinterface/servlet/msg/converter/NtMsgElementConverter.kt @@ -193,6 +193,7 @@ internal object NtMsgElementConverter { fileSize = image.fileSize.toULong(), peer = peerId, ) + MsgConstant.KCHATTYPEGUILD -> RichProtoSvc.getGuildPicDownUrl( originalUrl = originalUrl, md5 = md5, @@ -204,6 +205,7 @@ internal object NtMsgElementConverter { peer = peerId, subPeer = subPeer ) + else -> throw UnsupportedOperationException("Not supported chat type: $chatType") }, "subType" to image.picSubType, @@ -558,39 +560,35 @@ internal object NtMsgElementConverter { ): MessageSegment { val keyboard = element.inlineKeyboardElement return MessageSegment( - type = "inline_keyboard", + type = "button", data = mapOf( - "data" to buildJsonObject { - putJsonArray("rows") { - keyboard.rows.forEach { row -> - add(buildJsonObject row@{ - putJsonArray("buttons") { - row.buttons.forEach { button -> - add(buildJsonObject { - put("id", button.id ?: "") - put("label", button.label ?: "") - put("visited_label", button.visitedLabel ?: "") - put("style", button.style) - put("type", button.type) - put("click_limit", button.clickLimit) - put("unsupport_tips", button.unsupportTips ?: "") - put("data", button.data) - put("at_bot_show_channel_list", button.atBotShowChannelList) - put("permission_type", button.permissionType) - putJsonArray("specify_role_ids") { - button.specifyRoleIds?.forEach { add(it) } - } - putJsonArray("specify_tinyids") { - button.specifyTinyids?.forEach { add(it) } - } - }) - } - } - }) - } - } - put("bot_appid", keyboard.botAppid) - }.toString() + "rows" to keyboard.rows.map { row -> + mapOf("buttons" to row.buttons.map { button -> + mapOf( + "id" to button.id, + "render_data" to mapOf( + "label" to (button?.label ?: ""), + "visited_label" to (button?.visitedLabel ?: ""), + "style" to (button?.style ?: 0) + + ), + "action" to mapOf( + "type" to (button?.type ?: 0), + "permission" to mapOf( + "type" to (button?.permissionType ?: 0), + "specify_role_ids" to button?.specifyRoleIds, + "specify_user_ids" to button?.specifyTinyids + ), + "unsupport_tips" to (button?.unsupportTips ?: ""), + "data" to (button?.data ?: ""), + "reply" to button?.isReply, + "enter" to button?.enter + ) + ) + }) + + }, + "appid" to keyboard.botAppid ) ) } diff --git a/xposed/src/main/java/moe/fuqiuluo/qqinterface/servlet/msg/maker/ElemMaker.kt b/xposed/src/main/java/moe/fuqiuluo/qqinterface/servlet/msg/maker/ElemMaker.kt index 522ccb2c..6c82cc10 100644 --- a/xposed/src/main/java/moe/fuqiuluo/qqinterface/servlet/msg/maker/ElemMaker.kt +++ b/xposed/src/main/java/moe/fuqiuluo/qqinterface/servlet/msg/maker/ElemMaker.kt @@ -41,7 +41,6 @@ internal object ElemMaker { // "video" to ElemMaker::createVideoElem, "markdown" to ElemMaker::createMarkdownElem, "button" to ElemMaker::createButtonElem, - "inline_keyboard" to ElemMaker::createButtonElem, "dice" to ElemMaker::createNewDiceElem, "rps" to ElemMaker::createNewRpsElem, "poke" to ElemMaker::createPokeElem, diff --git a/xposed/src/main/java/moe/fuqiuluo/qqinterface/servlet/msg/maker/NtMsgElementMaker.kt b/xposed/src/main/java/moe/fuqiuluo/qqinterface/servlet/msg/maker/NtMsgElementMaker.kt index 181591b1..e09a97cf 100644 --- a/xposed/src/main/java/moe/fuqiuluo/qqinterface/servlet/msg/maker/NtMsgElementMaker.kt +++ b/xposed/src/main/java/moe/fuqiuluo/qqinterface/servlet/msg/maker/NtMsgElementMaker.kt @@ -97,37 +97,44 @@ internal object NtMsgElementMaker { peerId: String, data: JsonObject ): Result { - fun tryNewKeyboardButton(btn: JsonObject): InlineKeyboardButton { + fun tryNewKeyboardButton(button: JsonObject): InlineKeyboardButton { + val renderData = button["render_data"].asJsonObject + val action = button["action"].asJsonObject + val permission = action["permission"].asJsonObject return runCatching { InlineKeyboardButton( - btn["id"].asString, - btn["label"].asString, - btn["visited_label"].asString, - btn["style"].asInt, - btn["type"].asInt, - btn["click_limit"].asInt, - btn["unsupport_tips"].asString, - btn["data"].asString, - btn["at_bot_show_channel_list"].asBoolean, - btn["permission_type"].asInt, - ArrayList(btn["specify_role_ids"].asJsonArray.map { it.asString }), - ArrayList(btn["specify_tinyids"].asJsonArray.map { it.asString }), + button["id"].asStringOrNull ?: "", + renderData["label"].asString, + renderData["visited_label"].asString, + renderData["style"].asInt, + action["type"].asInt, + action["click_limit"].asInt, + action["unsupport_tips"].asString, + action["data"].asString, + action["at_bot_show_channel_list"].asBooleanOrNull ?: false, + permission["type"].asInt, + ArrayList(permission["specify_role_ids"].asJsonArrayOrNull?.map { id -> id.asString } + ?: arrayListOf()), + ArrayList(permission["specify_user_ids"].asJsonArrayOrNull?.map { id -> id.asString } + ?: arrayListOf()), false, 0, false, arrayListOf() ) }.getOrElse { InlineKeyboardButton( - btn["id"].asString, - btn["label"].asString, - btn["visited_label"].asString, - btn["style"].asInt, - btn["type"].asInt, - btn["click_limit"].asInt, - btn["unsupport_tips"].asString, - btn["data"].asString, - btn["at_bot_show_channel_list"].asBoolean, - btn["permission_type"].asInt, - ArrayList(btn["specify_role_ids"].asJsonArray.map { it.asString }), - ArrayList(btn["specify_tinyids"].asJsonArray.map { it.asString }), + button["id"].asStringOrNull ?: "", + renderData["label"].asString, + renderData["visited_label"].asString, + renderData["style"].asInt, + action["type"].asInt, + action["click_limit"].asInt, + action["unsupport_tips"].asString, + action["data"].asString, + action["at_bot_show_channel_list"].asBooleanOrNull ?: false, + permission["type"].asInt, + ArrayList(permission["specify_role_ids"].asJsonArrayOrNull?.map { id -> id.asString } + ?: arrayListOf()), + ArrayList(permission["specify_user_ids"].asJsonArrayOrNull?.map { id -> id.asString } + ?: arrayListOf()), ) } } diff --git a/xposed/src/main/java/moe/fuqiuluo/shamrock/remote/api/TestAction.kt b/xposed/src/main/java/moe/fuqiuluo/shamrock/remote/api/TestAction.kt index 79f8aa17..32b8de48 100644 --- a/xposed/src/main/java/moe/fuqiuluo/shamrock/remote/api/TestAction.kt +++ b/xposed/src/main/java/moe/fuqiuluo/shamrock/remote/api/TestAction.kt @@ -12,6 +12,7 @@ import moe.fuqiuluo.shamrock.helper.LogCenter import moe.fuqiuluo.shamrock.helper.MessageHelper import moe.fuqiuluo.shamrock.remote.action.handlers.SendMsgByResid import moe.fuqiuluo.shamrock.remote.service.config.ShamrockConfig +import moe.fuqiuluo.shamrock.tools.fetchOrNull import moe.fuqiuluo.shamrock.tools.fetchOrThrow import moe.fuqiuluo.shamrock.tools.getOrPost import moe.fuqiuluo.shamrock.xposed.helper.NTServiceFetcher