From 823d9911a0d4eb5e0215c3c85ae3c45c8a8e48a6 Mon Sep 17 00:00:00 2001 From: fuqiuluo Date: Tue, 16 Jul 2024 17:11:48 +0800 Subject: [PATCH] fix #338 --- app/build.gradle.kts | 2 +- .../java/kritor/service/GroupFileService.kt | 13 +++---- .../java/moe/fuqiuluo/shamrock/tools/Trpc.kt | 19 ++++++++++ .../fuqiuluo/shamrock/utils/PlatformUtils.kt | 1 + .../main/java/qq/service/bdh/RichProtoSvc.kt | 10 ++--- .../java/qq/service/contact/ContactHelper.kt | 4 +- .../java/qq/service/file/GroupFileHelper.kt | 38 ++----------------- .../main/java/qq/service/group/GroupHelper.kt | 12 ++++-- .../main/java/qq/service/msg/MessageHelper.kt | 7 ++-- .../java/qq/service/ticket/TicketHelper.kt | 4 +- 10 files changed, 49 insertions(+), 61 deletions(-) create mode 100644 xposed/src/main/java/moe/fuqiuluo/shamrock/tools/Trpc.kt diff --git a/app/build.gradle.kts b/app/build.gradle.kts index f2031351..1aea3c1c 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -17,7 +17,7 @@ android { minSdk = 27 targetSdk = 34 versionCode = getVersionCode() - versionName = "1.1.0" + ".r${getGitCommitCount()}." + getVersionName() + versionName = "1.1.1" + ".r${getGitCommitCount()}." + getVersionName() testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" vectorDrawables { diff --git a/xposed/src/main/java/kritor/service/GroupFileService.kt b/xposed/src/main/java/kritor/service/GroupFileService.kt index 41164764..7509f854 100644 --- a/xposed/src/main/java/kritor/service/GroupFileService.kt +++ b/xposed/src/main/java/kritor/service/GroupFileService.kt @@ -3,6 +3,7 @@ package kritor.service import io.grpc.Status import io.grpc.StatusRuntimeException import io.kritor.file.* +import moe.fuqiuluo.shamrock.tools.decodeToOidb import moe.fuqiuluo.shamrock.tools.slice import moe.fuqiuluo.symbols.decodeProtobuf import protobuf.auto.toByteArray @@ -33,8 +34,7 @@ internal object GroupFileService : GroupFileServiceGrpcKt.GroupFileServiceCorout if (fromServiceMsg.wupBuffer == null) { throw StatusRuntimeException(Status.INTERNAL.withDescription("oidb request failed")) } - val oidbPkg = oidb_sso.OIDBSSOPkg() - oidbPkg.mergeFrom(fromServiceMsg.wupBuffer.slice(4)) + val oidbPkg = fromServiceMsg.decodeToOidb() val rsp = oidbPkg.bytes_bodybuffer.get() .toByteArray() .decodeProtobuf() @@ -61,8 +61,7 @@ internal object GroupFileService : GroupFileServiceGrpcKt.GroupFileServiceCorout if (fromServiceMsg.wupBuffer == null) { throw StatusRuntimeException(Status.INTERNAL.withDescription("oidb request failed")) } - val oidbPkg = oidb_sso.OIDBSSOPkg() - oidbPkg.mergeFrom(fromServiceMsg.wupBuffer.slice(4)) + val oidbPkg = fromServiceMsg.decodeToOidb() val rsp = oidbPkg.bytes_bodybuffer.get().toByteArray().decodeProtobuf() if (rsp.deleteFolder?.retCode != 0) { throw StatusRuntimeException(Status.INTERNAL.withDescription("unable to delete folder: ${rsp.deleteFolder?.retCode}")) @@ -86,8 +85,7 @@ internal object GroupFileService : GroupFileServiceGrpcKt.GroupFileServiceCorout if (fromServiceMsg.wupBuffer == null) { throw StatusRuntimeException(Status.INTERNAL.withDescription("oidb request failed")) } - val oidbPkg = oidb_sso.OIDBSSOPkg() - oidbPkg.mergeFrom(fromServiceMsg.wupBuffer.slice(4)) + val oidbPkg = fromServiceMsg.decodeToOidb() val rsp = oidb_0x6d6.RspBody().apply { mergeFrom(oidbPkg.bytes_bodybuffer.get().toByteArray()) } @@ -112,8 +110,7 @@ internal object GroupFileService : GroupFileServiceGrpcKt.GroupFileServiceCorout if (fromServiceMsg.wupBuffer == null) { throw StatusRuntimeException(Status.INTERNAL.withDescription("oidb request failed")) } - val oidbPkg = oidb_sso.OIDBSSOPkg() - oidbPkg.mergeFrom(fromServiceMsg.wupBuffer.slice(4)) + val oidbPkg = fromServiceMsg.decodeToOidb() val rsp = oidbPkg.bytes_bodybuffer.get().toByteArray().decodeProtobuf() if (rsp.renameFolder?.retCode != 0) { throw StatusRuntimeException(Status.INTERNAL.withDescription("unable to rename folder: ${rsp.renameFolder?.retCode}")) diff --git a/xposed/src/main/java/moe/fuqiuluo/shamrock/tools/Trpc.kt b/xposed/src/main/java/moe/fuqiuluo/shamrock/tools/Trpc.kt new file mode 100644 index 00000000..b5f6771d --- /dev/null +++ b/xposed/src/main/java/moe/fuqiuluo/shamrock/tools/Trpc.kt @@ -0,0 +1,19 @@ +package moe.fuqiuluo.shamrock.tools + +import com.tencent.qphone.base.remote.FromServiceMsg +import moe.fuqiuluo.shamrock.helper.Level +import moe.fuqiuluo.shamrock.helper.LogCenter +import moe.fuqiuluo.shamrock.utils.DeflateTools +import tencent.im.oidb.oidb_sso + +fun FromServiceMsg.decodeToOidb(): oidb_sso.OIDBSSOPkg { + return kotlin.runCatching { + oidb_sso.OIDBSSOPkg().mergeFrom(wupBuffer.slice(4).let { + if (it[0] == 0x78.toByte()) DeflateTools.uncompress(it) else it + }) + }.getOrElse { + oidb_sso.OIDBSSOPkg().mergeFrom(wupBuffer.let { + if (it[0] == 0x78.toByte()) DeflateTools.uncompress(it) else it + }) + } +} \ No newline at end of file diff --git a/xposed/src/main/java/moe/fuqiuluo/shamrock/utils/PlatformUtils.kt b/xposed/src/main/java/moe/fuqiuluo/shamrock/utils/PlatformUtils.kt index 83f7d151..bba1f644 100644 --- a/xposed/src/main/java/moe/fuqiuluo/shamrock/utils/PlatformUtils.kt +++ b/xposed/src/main/java/moe/fuqiuluo/shamrock/utils/PlatformUtils.kt @@ -20,6 +20,7 @@ import kotlin.random.Random internal object PlatformUtils { const val QQ_9_0_8_VER = 5540 + const val QQ_9_0_65_VER = 6566 fun getQUA(): String { return "V1_AND_SQ_${getQQVersion(MobileQQ.getContext())}_${getQQVersionCode()}_YYB_D" diff --git a/xposed/src/main/java/qq/service/bdh/RichProtoSvc.kt b/xposed/src/main/java/qq/service/bdh/RichProtoSvc.kt index f8ac3a22..0139221e 100644 --- a/xposed/src/main/java/qq/service/bdh/RichProtoSvc.kt +++ b/xposed/src/main/java/qq/service/bdh/RichProtoSvc.kt @@ -10,6 +10,7 @@ import kotlinx.coroutines.suspendCancellableCoroutine import kotlinx.serialization.ExperimentalSerializationApi import moe.fuqiuluo.shamrock.helper.Level import moe.fuqiuluo.shamrock.helper.LogCenter +import moe.fuqiuluo.shamrock.tools.decodeToOidb import moe.fuqiuluo.shamrock.tools.slice import moe.fuqiuluo.shamrock.tools.toHexString import moe.fuqiuluo.shamrock.utils.PlatformUtils @@ -53,8 +54,7 @@ internal object RichProtoSvc: QQInterfaces() { if (fromServiceMsg == null || fromServiceMsg.wupBuffer == null) { return "" } - val body = oidb_sso.OIDBSSOPkg() - body.mergeFrom(fromServiceMsg.wupBuffer.slice(4)) + val body = fromServiceMsg.decodeToOidb() body.bytes_bodybuffer .get().toByteArray() .decodeProtobuf() @@ -82,8 +82,7 @@ internal object RichProtoSvc: QQInterfaces() { if (fromServiceMsg == null || fromServiceMsg.wupBuffer == null) { return "" } - val body = oidb_sso.OIDBSSOPkg() - body.mergeFrom(fromServiceMsg.wupBuffer.slice(4)) + val body = fromServiceMsg.decodeToOidb() val result = oidb_0x6d6.RspBody().mergeFrom(body.bytes_bodybuffer.get().toByteArray()) if (body.uint32_result.get() != 0 || result.download_file_rsp.int32_ret_code.get() != 0) { @@ -130,8 +129,7 @@ internal object RichProtoSvc: QQInterfaces() { } return "" } else { - val body = oidb_sso.OIDBSSOPkg() - body.mergeFrom(fromServiceMsg.wupBuffer.slice(4)) + val body = fromServiceMsg.decodeToOidb() val result = cmd0x346.RspBody().mergeFrom(cmd0xe37.Resp0xe37().mergeFrom( body.bytes_bodybuffer.get().toByteArray() ).bytes_cmd_0x346_rsp_body.get().toByteArray()) diff --git a/xposed/src/main/java/qq/service/contact/ContactHelper.kt b/xposed/src/main/java/qq/service/contact/ContactHelper.kt index 4bc7c74b..1c1ed487 100644 --- a/xposed/src/main/java/qq/service/contact/ContactHelper.kt +++ b/xposed/src/main/java/qq/service/contact/ContactHelper.kt @@ -11,6 +11,7 @@ import com.tencent.protofile.join_group_link.join_group_link import kotlinx.coroutines.suspendCancellableCoroutine import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.withLock +import moe.fuqiuluo.shamrock.tools.decodeToOidb import moe.fuqiuluo.shamrock.tools.slice import qq.service.internals.NTServiceFetcher import qq.service.QQInterfaces @@ -190,8 +191,7 @@ internal object ContactHelper: QQInterfaces() { val fromServiceMsg = sendOidbAW("OidbSvcTrpcTcp.0x11ca_0", 4790, 0, reqBody.toByteArray()) ?: error("unable to fetch contact ark_json_text") - val body = oidb_sso.OIDBSSOPkg() - body.mergeFrom(fromServiceMsg.wupBuffer.slice(4)) + val body = fromServiceMsg.decodeToOidb() val rsp = oidb_0x11b2.BusinessCardV3Rsp() rsp.mergeFrom(body.bytes_bodybuffer.get().toByteArray()) return rsp.signed_ark_msg.get() diff --git a/xposed/src/main/java/qq/service/file/GroupFileHelper.kt b/xposed/src/main/java/qq/service/file/GroupFileHelper.kt index c106b6aa..36d42dc0 100644 --- a/xposed/src/main/java/qq/service/file/GroupFileHelper.kt +++ b/xposed/src/main/java/qq/service/file/GroupFileHelper.kt @@ -1,5 +1,3 @@ -@file:OptIn(ExperimentalStdlibApi::class) - package qq.service.file import com.tencent.mobileqq.pb.ByteStringMicro @@ -9,6 +7,7 @@ import io.kritor.file.* import moe.fuqiuluo.shamrock.helper.Level import moe.fuqiuluo.shamrock.helper.LogCenter import moe.fuqiuluo.shamrock.tools.EMPTY_BYTE_ARRAY +import moe.fuqiuluo.shamrock.tools.decodeToOidb import moe.fuqiuluo.shamrock.tools.slice import moe.fuqiuluo.shamrock.tools.toHexString import moe.fuqiuluo.shamrock.utils.DeflateTools @@ -32,16 +31,7 @@ internal object GroupFileHelper: QQInterfaces() { val fileCnt: Int val limitCnt: Int if (fromServiceMsg.wupBuffer != null) { - val oidb1 = kotlin.runCatching { - oidb_sso.OIDBSSOPkg().mergeFrom(fromServiceMsg.wupBuffer.let { - if (it[0] == 0x78.toByte()) DeflateTools.uncompress(it) else it - }) - }.getOrElse { - LogCenter.log("unable to parse oidb response(OidbSvc.0x6d8_1): ${fromServiceMsg.wupBuffer.toHexString()}, ${it.stackTraceToString()}", Level.ERROR) - oidb_sso.OIDBSSOPkg().mergeFrom(fromServiceMsg.wupBuffer.slice(4).let { - if (it[0] == 0x78.toByte()) DeflateTools.uncompress(it) else it - }) - } + val oidb1 = fromServiceMsg.decodeToOidb() oidb_0x6d8.RspBody().mergeFrom(oidb1.bytes_bodybuffer.get().toByteArray()).group_file_cnt_rsp.apply { fileCnt = uint32_all_file_count.get() @@ -60,17 +50,7 @@ internal object GroupFileHelper: QQInterfaces() { val totalSpace: Long val usedSpace: Long if (fromServiceMsg2.isSuccess && fromServiceMsg2.wupBuffer != null) { - val oidb2 = kotlin.runCatching { - oidb_sso.OIDBSSOPkg().mergeFrom(fromServiceMsg2.wupBuffer.let { - if (it[0] == 0x78.toByte()) DeflateTools.uncompress(it) else it - }) - }.onFailure { - LogCenter.log("unable to parse oidb response(OidbSvc.0x6d8_1): ${fromServiceMsg2.wupBuffer.toHexString()}, ${it.stackTraceToString()}", Level.ERROR) - }.getOrElse { - oidb_sso.OIDBSSOPkg().mergeFrom(fromServiceMsg2.wupBuffer.slice(4).let { - if (it[0] == 0x78.toByte()) DeflateTools.uncompress(it) else it - }) - } + val oidb2 = fromServiceMsg2.decodeToOidb() oidb_0x6d8.RspBody().mergeFrom(oidb2.bytes_bodybuffer.get().toByteArray()).group_space_rsp.apply { totalSpace = uint64_total_space.get() @@ -117,17 +97,7 @@ internal object GroupFileHelper: QQInterfaces() { val files = arrayListOf() val folders = arrayListOf() if (fromServiceMsg.wupBuffer != null) { - val oidb = kotlin.runCatching { - oidb_sso.OIDBSSOPkg().mergeFrom(fromServiceMsg.wupBuffer.slice(4).let { - if (it[0] == 0x78.toByte()) DeflateTools.uncompress(it) else it - }) - }.onFailure { - LogCenter.log("unable to parse oidb response: ${fromServiceMsg.wupBuffer.toHexString()}", Level.ERROR) - }.getOrElse { - oidb_sso.OIDBSSOPkg().mergeFrom(fromServiceMsg.wupBuffer.let { - if (it[0] == 0x78.toByte()) DeflateTools.uncompress(it) else it - }) - } + val oidb = fromServiceMsg.decodeToOidb() oidb_0x6d8.RspBody().mergeFrom(oidb.bytes_bodybuffer.get().toByteArray()) .file_list_info_rsp.apply { diff --git a/xposed/src/main/java/qq/service/group/GroupHelper.kt b/xposed/src/main/java/qq/service/group/GroupHelper.kt index 27a837c3..aaa54bfa 100644 --- a/xposed/src/main/java/qq/service/group/GroupHelper.kt +++ b/xposed/src/main/java/qq/service/group/GroupHelper.kt @@ -19,10 +19,13 @@ import kotlinx.coroutines.sync.withLock import kotlinx.coroutines.withTimeoutOrNull import moe.fuqiuluo.shamrock.helper.Level import moe.fuqiuluo.shamrock.helper.LogCenter +import moe.fuqiuluo.shamrock.tools.decodeToOidb import qq.service.internals.NTServiceFetcher import moe.fuqiuluo.shamrock.tools.ifNullOrEmpty import moe.fuqiuluo.shamrock.tools.putBuf32Long import moe.fuqiuluo.shamrock.tools.slice +import moe.fuqiuluo.shamrock.utils.PlatformUtils +import moe.fuqiuluo.shamrock.utils.PlatformUtils.QQ_9_0_65_VER import protobuf.auto.toByteArray import protobuf.oidb.cmd0xf16.Oidb0xf16 import protobuf.oidb.cmd0xf16.SetGroupRemarkReq @@ -453,8 +456,7 @@ internal object GroupHelper: QQInterfaces() { if (fromServiceMsg.wupBuffer == null) { return Result.failure(RuntimeException("[oidb] failed")) } - val body = oidb_sso.OIDBSSOPkg() - body.mergeFrom(fromServiceMsg.wupBuffer.slice(4)) + val body = fromServiceMsg.decodeToOidb() if(body.uint32_result.get() != 0) { return Result.failure(RuntimeException(body.str_error_msg.get())) } @@ -475,8 +477,7 @@ internal object GroupHelper: QQInterfaces() { if (fromServiceMsg.wupBuffer == null) { return Result.failure(RuntimeException("[oidb] failed")) } - val body = oidb_sso.OIDBSSOPkg() - body.mergeFrom(fromServiceMsg.wupBuffer.slice(4)) + val body = fromServiceMsg.decodeToOidb() if(body.uint32_result.get() != 0) { return Result.failure(RuntimeException(body.str_error_msg.get())) } @@ -637,6 +638,9 @@ internal object GroupHelper: QQInterfaces() { } private suspend fun requestTroopMemberInfo(service: ITroopMemberInfoService, groupId: String, memberUin: String, timeout: Long = 10_000): Result { + if(PlatformUtils.getQQVersionCode() >= QQ_9_0_65_VER) { + return Result.failure(Exception("当前版本不支持该API")) + } val info = RefreshTroopMemberInfoLock.withLock { service.deleteTroopMember(groupId, memberUin) diff --git a/xposed/src/main/java/qq/service/msg/MessageHelper.kt b/xposed/src/main/java/qq/service/msg/MessageHelper.kt index dd776b1a..c4de6761 100644 --- a/xposed/src/main/java/qq/service/msg/MessageHelper.kt +++ b/xposed/src/main/java/qq/service/msg/MessageHelper.kt @@ -31,6 +31,7 @@ import moe.fuqiuluo.shamrock.tools.asJsonObject import moe.fuqiuluo.shamrock.tools.asLong import moe.fuqiuluo.shamrock.tools.asString import moe.fuqiuluo.shamrock.tools.asStringOrNull +import moe.fuqiuluo.shamrock.tools.decodeToOidb import moe.fuqiuluo.shamrock.tools.slice import moe.fuqiuluo.shamrock.tools.toHexString import moe.fuqiuluo.shamrock.utils.DeflateTools @@ -108,8 +109,7 @@ internal object MessageHelper: QQInterfaces() { if (fromServiceMsg?.wupBuffer == null) { return "no response" } - val body = oidb_sso.OIDBSSOPkg() - body.mergeFrom(fromServiceMsg.wupBuffer.slice(4)) + val body = fromServiceMsg.decodeToOidb() val result = oidb_0xeac.RspBody().mergeFrom(body.bytes_bodybuffer.get().toByteArray()) return if (result.wording.has()) { LogCenter.log("设置群精华失败: ${result.wording.get()}", Level.WARN) @@ -129,8 +129,7 @@ internal object MessageHelper: QQInterfaces() { if (fromServiceMsg?.wupBuffer == null) { return "no response" } - val body = oidb_sso.OIDBSSOPkg() - body.mergeFrom(fromServiceMsg.wupBuffer.slice(4)) + val body = fromServiceMsg.decodeToOidb() val result = oidb_0xeac.RspBody().mergeFrom(body.bytes_bodybuffer.get().toByteArray()) return if (result.wording.has()) { LogCenter.log("移除群精华失败: ${result.wording.get()}", Level.WARN) diff --git a/xposed/src/main/java/qq/service/ticket/TicketHelper.kt b/xposed/src/main/java/qq/service/ticket/TicketHelper.kt index 955d583c..1dbb0d83 100644 --- a/xposed/src/main/java/qq/service/ticket/TicketHelper.kt +++ b/xposed/src/main/java/qq/service/ticket/TicketHelper.kt @@ -10,6 +10,7 @@ import io.ktor.client.plugins.HttpTimeout import io.ktor.client.request.get import io.ktor.client.request.header import moe.fuqiuluo.shamrock.tools.GlobalClient +import moe.fuqiuluo.shamrock.tools.decodeToOidb import moe.fuqiuluo.shamrock.tools.slice import mqq.app.MobileQQ import mqq.manager.TicketManager @@ -140,8 +141,7 @@ internal object TicketHelper: QQInterfaces() { val fromServiceMsg = sendOidbAW("OidbSvcTcp.0x102a", 4138, 0, req.toByteArray()) ?: return Result.failure(Exception("getLessPSKey failed")) if (fromServiceMsg.wupBuffer == null) return Result.failure(Exception("getLessPSKey failed: no response")) - val body = oidb_sso.OIDBSSOPkg() - body.mergeFrom(fromServiceMsg.wupBuffer.slice(4)) + val body = fromServiceMsg.decodeToOidb() val rsp = oidb_cmd0x102a.GetPSkeyResponse().mergeFrom(body.bytes_bodybuffer.get().toByteArray()) return Result.success(rsp.private_keys.get()) }