Shamrock: 快速序列化/反序列化 Protobuf

Signed-off-by: 白池 <whitechi73@outlook.com>
This commit is contained in:
白池 2024-02-23 18:23:02 +08:00
parent 9bbcc2f160
commit b4c40e236a
54 changed files with 380 additions and 175 deletions

View File

@ -6,4 +6,9 @@ plugins {
java { java {
sourceCompatibility = JavaVersion.VERSION_17 sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17 targetCompatibility = JavaVersion.VERSION_17
}
dependencies {
implementation(DEPENDENCY_PROTOBUF)
implementation(kotlinx("serialization-protobuf", "1.6.2"))
} }

View File

@ -0,0 +1,16 @@
package moe.fuqiuluo.symbols
import kotlinx.serialization.decodeFromByteArray
import kotlinx.serialization.protobuf.ProtoBuf
import kotlin.reflect.KClass
interface Protobuf<T: Protobuf<T>>
inline fun <reified T: Protobuf<T>> KClass<T>.decode(data: ByteArray): T {
return ProtoBuf.decodeFromByteArray(data)
}
inline fun <reified T: Protobuf<T>> ByteArray.decodeProtobuf(to: KClass<T>? = null): T {
return ProtoBuf.decodeFromByteArray(this)
}

View File

@ -1,6 +1,7 @@
plugins { plugins {
kotlin("jvm") kotlin("jvm")
id("com.google.devtools.ksp") version "1.9.21-1.0.15" id("com.google.devtools.ksp") version "1.9.21-1.0.15"
kotlin("plugin.serialization") version "1.9.21"
} }
ksp { ksp {
@ -14,5 +15,8 @@ dependencies {
implementation("com.google.devtools.ksp:symbol-processing-api:1.9.21-1.0.15") implementation("com.google.devtools.ksp:symbol-processing-api:1.9.21-1.0.15")
implementation("com.squareup:kotlinpoet:1.14.2") implementation("com.squareup:kotlinpoet:1.14.2")
implementation(DEPENDENCY_PROTOBUF)
implementation(kotlinx("serialization-protobuf", "1.6.2"))
ksp("dev.zacsweers.autoservice:auto-service-ksp:1.1.0") ksp("dev.zacsweers.autoservice:auto-service-ksp:1.1.0")
} }

View File

@ -6,6 +6,7 @@ package moe.fuqiuluo.ksp.impl
import com.google.devtools.ksp.KspExperimental import com.google.devtools.ksp.KspExperimental
import com.google.devtools.ksp.getAnnotationsByType import com.google.devtools.ksp.getAnnotationsByType
import com.google.devtools.ksp.getClassDeclarationByName import com.google.devtools.ksp.getClassDeclarationByName
import com.google.devtools.ksp.getKotlinClassByName
import com.google.devtools.ksp.processing.CodeGenerator import com.google.devtools.ksp.processing.CodeGenerator
import com.google.devtools.ksp.processing.Dependencies import com.google.devtools.ksp.processing.Dependencies
import com.google.devtools.ksp.processing.KSPLogger import com.google.devtools.ksp.processing.KSPLogger
@ -26,18 +27,18 @@ class OneBotHandlerProcessor(
): SymbolProcessor { ): SymbolProcessor {
override fun process(resolver: Resolver): List<KSAnnotated> { override fun process(resolver: Resolver): List<KSAnnotated> {
val ActionManagerNode = resolver.getClassDeclarationByName("moe.fuqiuluo.shamrock.remote.action.ActionManager") val ActionManagerNode = resolver.getClassDeclarationByName("moe.fuqiuluo.shamrock.remote.action.ActionManager")
if (ActionManagerNode == null) { ?: resolver.getKotlinClassByName("moe.fuqiuluo.shamrock.remote.action.ActionManager")
logger.error("OneBotHandlerProcessor: ActionManager not found") ?: resolver.getClassDeclarationByName("ActionManager")
return emptyList()
}
val symbols = resolver.getSymbolsWithAnnotation(OneBotHandler::class.qualifiedName!!) val symbols = resolver.getSymbolsWithAnnotation(OneBotHandler::class.qualifiedName!!)
val unableToProcess = symbols.filterNot { it.validate() } val unableToProcess = symbols.filterNot { it.validate() }
val oneBotHandlers = (symbols.filter { if (ActionManagerNode != null) {
it is KSClassDeclaration && it.validate() && it.classKind == ClassKind.OBJECT val oneBotHandlers = (symbols.filter {
} as Sequence<KSClassDeclaration>).toList() it is KSClassDeclaration && it.validate() && it.classKind == ClassKind.OBJECT
} as Sequence<KSClassDeclaration>).toList()
if (oneBotHandlers.isNotEmpty()) { if (oneBotHandlers.isNotEmpty()) {
ActionManagerNode.accept(ActionManagerVisitor(oneBotHandlers), Unit) ActionManagerNode.accept(ActionManagerVisitor(oneBotHandlers), Unit)
}
} }
return unableToProcess.toList() return unableToProcess.toList()

View File

@ -0,0 +1,77 @@
@file:Suppress("UNCHECKED_CAST")
package moe.fuqiuluo.ksp.impl
import com.google.devtools.ksp.isInternal
import com.google.devtools.ksp.isPrivate
import com.google.devtools.ksp.processing.CodeGenerator
import com.google.devtools.ksp.processing.Dependencies
import com.google.devtools.ksp.processing.KSPLogger
import com.google.devtools.ksp.processing.Resolver
import com.google.devtools.ksp.processing.SymbolProcessor
import com.google.devtools.ksp.symbol.ClassKind
import com.google.devtools.ksp.symbol.KSAnnotated
import com.google.devtools.ksp.symbol.KSClassDeclaration
import com.google.devtools.ksp.symbol.KSDeclaration
import com.google.devtools.ksp.validate
import com.squareup.kotlinpoet.FileSpec
import kotlinx.serialization.Serializable
class ProtobufProcessor(
private val codeGenerator: CodeGenerator,
private val logger: KSPLogger
): SymbolProcessor {
override fun process(resolver: Resolver): List<KSAnnotated> {
val symbols = resolver.getSymbolsWithAnnotation(Serializable::class.qualifiedName!!)
val unableToProcess = symbols.filterNot { it.validate() }
val actions = (symbols.filter {
it is KSClassDeclaration && it.validate() && it.classKind == ClassKind.CLASS
} as Sequence<KSClassDeclaration>).filter {
it.superTypes.any { superType ->
superType.resolve().declaration.qualifiedName?.asString() == "moe.fuqiuluo.symbols.Protobuf"
}
}.toList()
if (actions.isNotEmpty()) {
actions.forEach { clz ->
if (clz.isInternal()) return@forEach
if (clz.isPrivate()) return@forEach
val packageName = "protobuf.auto"
val fileSpecBuilder = FileSpec.scriptBuilder("FastProtobuf", packageName)
fileSpecBuilder.addImport("kotlinx.serialization.protobuf", "ProtoBuf")
fileSpecBuilder.addImport("kotlinx.serialization", "decodeFromByteArray")
fileSpecBuilder.addImport("kotlinx.serialization", "encodeToByteArray")
if (clz.parentDeclaration != null) {
fileSpecBuilder.addImport(clz.importPackage, clz.simpleName.asString())
} else {
fileSpecBuilder.addImport(clz.packageName.asString(), clz.simpleName.asString())
}
if (clz.typeParameters.isNotEmpty()) {
val genericType = clz.typeParameters.joinToString(", ") { it.name.asString() }
fileSpecBuilder.addStatement("""inline fun <$genericType> ${clz.simpleName.asString()}<$genericType>.toByteArray() = ProtoBuf.encodeToByteArray(this)""")
} else {
fileSpecBuilder.addStatement("inline fun ${clz.simpleName.asString()}.toByteArray() = ProtoBuf.encodeToByteArray(this)")
}
codeGenerator.createNewFile(
dependencies = Dependencies.ALL_FILES,
packageName = packageName,
fileName = clz.simpleName.asString() + "\$FP"
).use { outputStream ->
outputStream.writer().use {
fileSpecBuilder.build().writeTo(it)
}
}
}
}
return unableToProcess.toList()
}
private val KSDeclaration.importPackage: String
get() = if (parentDeclaration != null) {
parentDeclaration!!.importPackage + "." + parentDeclaration!!.simpleName.asString()
} else packageName.asString()
}

View File

@ -0,0 +1,17 @@
package moe.fuqiuluo.ksp.providers
import com.google.auto.service.AutoService
import com.google.devtools.ksp.processing.SymbolProcessor
import com.google.devtools.ksp.processing.SymbolProcessorEnvironment
import com.google.devtools.ksp.processing.SymbolProcessorProvider
import moe.fuqiuluo.ksp.impl.ProtobufProcessor
@AutoService(SymbolProcessorProvider::class)
class ProtobufProvider: SymbolProcessorProvider {
override fun create(environment: SymbolProcessorEnvironment): SymbolProcessor {
return ProtobufProcessor(
environment.codeGenerator,
environment.logger
)
}
}

View File

@ -2,6 +2,7 @@ plugins {
id("com.android.library") id("com.android.library")
id("org.jetbrains.kotlin.android") id("org.jetbrains.kotlin.android")
kotlin("plugin.serialization") version "1.9.21" kotlin("plugin.serialization") version "1.9.21"
id("com.google.devtools.ksp") version "1.9.21-1.0.15"
} }
android { android {
@ -38,4 +39,7 @@ dependencies {
implementation(kotlinx("serialization-protobuf", "1.6.2")) implementation(kotlinx("serialization-protobuf", "1.6.2"))
implementation(kotlinx("serialization-json", "1.6.2")) implementation(kotlinx("serialization-json", "1.6.2"))
implementation(project(":annotations"))
ksp(project(":processor"))
} }

View File

@ -2,9 +2,10 @@ package protobuf.fav
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoNumber import kotlinx.serialization.protobuf.ProtoNumber
import moe.fuqiuluo.symbols.Protobuf
@Serializable @Serializable
data class WeiyunComm( data class WeiyunComm(
@ProtoNumber(1) val req: WeiyunCommonReq? = null, @ProtoNumber(1) val req: WeiyunCommonReq? = null,
@ProtoNumber(2) val resp: WeiyunCommonResp? = null @ProtoNumber(2) val resp: WeiyunCommonResp? = null
) ): Protobuf<WeiyunComm>

View File

@ -6,6 +6,7 @@ package protobuf.fav
import kotlinx.serialization.ExperimentalSerializationApi import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoNumber import kotlinx.serialization.protobuf.ProtoNumber
import moe.fuqiuluo.symbols.Protobuf
@Serializable @Serializable
data class WeiyunMsgHead( data class WeiyunMsgHead(
@ -27,4 +28,5 @@ data class WeiyunMsgHead(
@ProtoNumber(103) val promptMsg: String? = null, @ProtoNumber(103) val promptMsg: String? = null,
@ProtoNumber(111) val totalSpace: ULong = ULong.MIN_VALUE, @ProtoNumber(111) val totalSpace: ULong = ULong.MIN_VALUE,
@ProtoNumber(112) val usedSpace: ULong = ULong.MIN_VALUE, @ProtoNumber(112) val usedSpace: ULong = ULong.MIN_VALUE,
) ): Protobuf<WeiyunMsgHead>

View File

@ -6,6 +6,7 @@ import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.SerialName import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoNumber import kotlinx.serialization.protobuf.ProtoNumber
import moe.fuqiuluo.symbols.Protobuf
import protobuf.qweb.QWebExtInfo import protobuf.qweb.QWebExtInfo
@Serializable @Serializable
@ -19,7 +20,7 @@ data class GetGuildFeedsReq(
@ProtoNumber(7) var u7: Int? = null, @ProtoNumber(7) var u7: Int? = null,
@ProtoNumber(8) var u8: Int? = null, @ProtoNumber(8) var u8: Int? = null,
@ProtoNumber(9) var u9: ByteArray? = null, @ProtoNumber(9) var u9: ByteArray? = null,
) ): Protobuf<GetGuildFeedsReq>
@Serializable @Serializable
data class GetGuildFeedsRsp( data class GetGuildFeedsRsp(
@ -27,7 +28,7 @@ data class GetGuildFeedsRsp(
@ProtoNumber(2) var isFinish: Int = 0, @ProtoNumber(2) var isFinish: Int = 0,
//@ProtoNumber(3) var feedAttchInfo: ByteArray? = null, //@ProtoNumber(3) var feedAttchInfo: ByteArray? = null,
//@ProtoNumber(4) var traceId: String? = null, //@ProtoNumber(4) var traceId: String? = null,
) ): Protobuf<GetGuildFeedsRsp>
@Serializable @Serializable
data class StFeed( data class StFeed(

View File

@ -0,0 +1,37 @@
@file:OptIn(ExperimentalSerializationApi::class)
package protobuf.lightapp
import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoNumber
import moe.fuqiuluo.symbols.Protobuf
@Serializable
data class AdaptShareInfoReq(
//@ProtoNumber(1) var extInfo: Any? = null,
@ProtoNumber(2) var appid: String? = null,
@ProtoNumber(3) var title: String? = null,
@ProtoNumber(4) var desc: String? = null,
@ProtoNumber(5) var time: ULong? = null,
@ProtoNumber(6) var scene: UInt? = null,
@ProtoNumber(7) var templetType: UInt? = null,
@ProtoNumber(8) var businessType: UInt? = null,
@ProtoNumber(9) var picUrl: String? = null,
@ProtoNumber(10) var vidUrl: String? = null,
@ProtoNumber(11) var jumpUrl: String? = null,
@ProtoNumber(12) var iconUrl: String? = null,
@ProtoNumber(13) var verType: UInt? = null,
@ProtoNumber(14) var shareType: UInt? = null,
@ProtoNumber(15) var versionId: String? = null,
@ProtoNumber(16) var withShareTicket: UInt? = null,
@ProtoNumber(17) var webURL: String? = null,
//@ProtoNumber(18) var appidRich: Any? = null,
@ProtoNumber(19) var template: Template? = null,
//@ProtoNumber(20) var rcvOpenId: Any? = null,
): Protobuf<AdaptShareInfoReq>
@Serializable
data class Template(
@ProtoNumber(1) var templateId: UInt? = null,
@ProtoNumber(2) var templateData: ByteArray? = null,
)

View File

@ -4,6 +4,7 @@ package protobuf.message.longmsg
import kotlinx.serialization.ExperimentalSerializationApi import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoNumber import kotlinx.serialization.protobuf.ProtoNumber
import moe.fuqiuluo.symbols.Protobuf
@Serializable @Serializable
@ -39,14 +40,14 @@ data class LongMsgReq(
@ProtoNumber(1) val recvInfo: RecvLongMsgInfo? = null, @ProtoNumber(1) val recvInfo: RecvLongMsgInfo? = null,
@ProtoNumber(2) val sendInfo: SendLongMsgInfo? = null, @ProtoNumber(2) val sendInfo: SendLongMsgInfo? = null,
@ProtoNumber(15) val setting: LongMsgSettings? = null, @ProtoNumber(15) val setting: LongMsgSettings? = null,
) ): Protobuf<LongMsgReq>
@Serializable @Serializable
data class LongMsgRsp( data class LongMsgRsp(
@ProtoNumber(1) val recvResult: RecvLongMsgResult? = null, @ProtoNumber(1) val recvResult: RecvLongMsgResult? = null,
@ProtoNumber(2) val sendResult: SendLongMsgResult? = null, @ProtoNumber(2) val sendResult: SendLongMsgResult? = null,
@ProtoNumber(15) val setting: LongMsgSettings? = null @ProtoNumber(15) val setting: LongMsgSettings? = null
) { ): Protobuf<LongMsgRsp> {
companion object { companion object {
@Serializable @Serializable
data class SendLongMsgResult( data class SendLongMsgResult(

View File

@ -5,6 +5,7 @@ package protobuf.message.longmsg
import kotlinx.serialization.ExperimentalSerializationApi import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoNumber import kotlinx.serialization.protobuf.ProtoNumber
import moe.fuqiuluo.symbols.Protobuf
import protobuf.message.MessageBody import protobuf.message.MessageBody
import protobuf.message.MessageContent import protobuf.message.MessageContent
import protobuf.message.MessageHead import protobuf.message.MessageHead
@ -29,4 +30,4 @@ data class LongMsgAction(
@Serializable @Serializable
data class LongMsgPayload( data class LongMsgPayload(
@ProtoNumber(2) val action: List<LongMsgAction>? = null @ProtoNumber(2) val action: List<LongMsgAction>? = null
) ): Protobuf<LongMsgPayload>

View File

@ -4,12 +4,13 @@ package protobuf.message.multimedia
import kotlinx.serialization.ExperimentalSerializationApi import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoNumber import kotlinx.serialization.protobuf.ProtoNumber
import moe.fuqiuluo.symbols.Protobuf
@Serializable @Serializable
data class RichMediaForPicData( data class RichMediaForPicData(
@ProtoNumber(1) val info: MediaInfo?, @ProtoNumber(1) val info: MediaInfo?,
@ProtoNumber(2) val display: DisplayMediaInfo?, @ProtoNumber(2) val display: DisplayMediaInfo?,
) { ): Protobuf<RichMediaForPicData> {
companion object { companion object {
@Serializable @Serializable
data class MediaInfo( data class MediaInfo(

View File

@ -2,6 +2,7 @@ package protobuf.msg
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoNumber import kotlinx.serialization.protobuf.ProtoNumber
import moe.fuqiuluo.symbols.Protobuf
@Serializable @Serializable
class PbSendMsgReq( class PbSendMsgReq(
@ -19,7 +20,7 @@ class PbSendMsgReq(
//@ProtoNumber(12) var msgCtrl: MsgCtrl? = null, //@ProtoNumber(12) var msgCtrl: MsgCtrl? = null,
//@ProtoNumber(13) var receipt_req: ReceiptReq? = null, //@ProtoNumber(13) var receipt_req: ReceiptReq? = null,
//@ProtoNumber(14) var multi_send_seq: UInt = 0u, //@ProtoNumber(14) var multi_send_seq: UInt = 0u,
) ): Protobuf<PbSendMsgReq>
@Serializable @Serializable
data class ContentHead( data class ContentHead(

View File

@ -2,6 +2,7 @@ package protobuf.oidb
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoNumber import kotlinx.serialization.protobuf.ProtoNumber
import moe.fuqiuluo.symbols.Protobuf
@Serializable @Serializable
data class TrpcOidb( data class TrpcOidb(
@ -9,4 +10,4 @@ data class TrpcOidb(
@ProtoNumber(2) val service: Int = Int.MIN_VALUE, @ProtoNumber(2) val service: Int = Int.MIN_VALUE,
@ProtoNumber(4) val buffer: ByteArray, @ProtoNumber(4) val buffer: ByteArray,
@ProtoNumber(12) val flag: Int = Int.MIN_VALUE, @ProtoNumber(12) val flag: Int = Int.MIN_VALUE,
) ): Protobuf<TrpcOidb>

View File

@ -5,6 +5,7 @@ package protobuf.oidb.cmd0x6d7
import kotlinx.serialization.ExperimentalSerializationApi import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoNumber import kotlinx.serialization.protobuf.ProtoNumber
import moe.fuqiuluo.symbols.Protobuf
import protobuf.group_file_common.FolderInfo import protobuf.group_file_common.FolderInfo
@Serializable @Serializable
@ -13,7 +14,7 @@ data class Oidb0x6d7ReqBody(
@ProtoNumber(2) val deleteFolder: DeleteFolderReq? = null, @ProtoNumber(2) val deleteFolder: DeleteFolderReq? = null,
@ProtoNumber(3) val moveFolder: MoveFolderReq? = null, @ProtoNumber(3) val moveFolder: MoveFolderReq? = null,
@ProtoNumber(4) val renameFolder: RenameFolderReq? = null, @ProtoNumber(4) val renameFolder: RenameFolderReq? = null,
) ): Protobuf<Oidb0x6d7ReqBody>
@Serializable @Serializable
data class CreateFolderReq( data class CreateFolderReq(
@ -53,7 +54,7 @@ data class Oidb0x6d7RespBody(
@ProtoNumber(2) val deleteFolder: DeleteFolderResp? = null, @ProtoNumber(2) val deleteFolder: DeleteFolderResp? = null,
@ProtoNumber(3) val moveFolder: MoveFolderResp? = null, @ProtoNumber(3) val moveFolder: MoveFolderResp? = null,
@ProtoNumber(4) val renameFolder: RenameFolderResp? = null, @ProtoNumber(4) val renameFolder: RenameFolderResp? = null,
) ): Protobuf<Oidb0x6d7RespBody>
@Serializable @Serializable
data class CreateFolderResp( data class CreateFolderResp(

View File

@ -2,6 +2,7 @@ package protobuf.oidb.cmd0x9082
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoNumber import kotlinx.serialization.protobuf.ProtoNumber
import moe.fuqiuluo.symbols.Protobuf
@Serializable @Serializable
data class Oidb0x9082( data class Oidb0x9082(
@ -11,4 +12,4 @@ data class Oidb0x9082(
@ProtoNumber(5) val flag: UInt = UInt.MIN_VALUE, @ProtoNumber(5) val flag: UInt = UInt.MIN_VALUE,
@ProtoNumber(6) val u1: UInt = UInt.MIN_VALUE, @ProtoNumber(6) val u1: UInt = UInt.MIN_VALUE,
@ProtoNumber(7) val u2: UInt = UInt.MIN_VALUE, @ProtoNumber(7) val u2: UInt = UInt.MIN_VALUE,
) ): Protobuf<Oidb0x9082>

View File

@ -2,11 +2,12 @@ package protobuf.oidb.cmd0xf16
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoNumber import kotlinx.serialization.protobuf.ProtoNumber
import moe.fuqiuluo.symbols.Protobuf
@Serializable @Serializable
data class Oidb0xf16( data class Oidb0xf16(
@ProtoNumber(1) var setGroupRemarkReq: SetGroupRemarkReq? = null, @ProtoNumber(1) var setGroupRemarkReq: SetGroupRemarkReq? = null,
) ): Protobuf<Oidb0xf16>
@Serializable @Serializable
data class SetGroupRemarkReq( data class SetGroupRemarkReq(

View File

@ -5,6 +5,7 @@ package protobuf.oidb.cmd0xf88
import kotlinx.serialization.ExperimentalSerializationApi import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoNumber import kotlinx.serialization.protobuf.ProtoNumber
import moe.fuqiuluo.symbols.Protobuf
@Serializable @Serializable
data class Oidb0xf88Req( data class Oidb0xf88Req(
@ -12,12 +13,12 @@ data class Oidb0xf88Req(
@ProtoNumber(2) val memberId: ULong, @ProtoNumber(2) val memberId: ULong,
@ProtoNumber(3) val tinyId: ULong, @ProtoNumber(3) val tinyId: ULong,
@ProtoNumber(4) val guildId: ULong, @ProtoNumber(4) val guildId: ULong,
) ): Protobuf<Oidb0xf88Req>
@Serializable @Serializable
data class Oidb0xf88Rsp( data class Oidb0xf88Rsp(
@ProtoNumber(1) val userInfo: GProUserInfo? @ProtoNumber(1) val userInfo: GProUserInfo?
) ): Protobuf<Oidb0xf88Rsp>
@Serializable @Serializable
data class GProUserInfo( data class GProUserInfo(

View File

@ -4,6 +4,7 @@ package protobuf.oidb.cmd0xfc2
import kotlinx.serialization.ExperimentalSerializationApi import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoNumber import kotlinx.serialization.protobuf.ProtoNumber
import moe.fuqiuluo.symbols.Protobuf
@Serializable @Serializable
data class Oidb0xfc2ReqBody( data class Oidb0xfc2ReqBody(
@ -16,7 +17,7 @@ data class Oidb0xfc2ReqBody(
@ProtoNumber(300) var msgApplyDownloadReq: Oidb0xfc2MsgApplyDownloadReq? = null, @ProtoNumber(300) var msgApplyDownloadReq: Oidb0xfc2MsgApplyDownloadReq? = null,
//@ProtoNumber(400) var msg_apply_preview_req: Any? = null, //@ProtoNumber(400) var msg_apply_preview_req: Any? = null,
//@ProtoNumber(500) var msg_apply_security_strike_req: Any? = null, //@ProtoNumber(500) var msg_apply_security_strike_req: Any? = null,
) ): Protobuf<Oidb0xfc2ReqBody>
@Serializable @Serializable
data class Oidb0xfc2RspBody( data class Oidb0xfc2RspBody(
@ -27,7 +28,7 @@ data class Oidb0xfc2RspBody(
@ProtoNumber(310) var msgApplyDownloadRsp: Oidb0xfc2MsgApplyDownloadRsp? = null, @ProtoNumber(310) var msgApplyDownloadRsp: Oidb0xfc2MsgApplyDownloadRsp? = null,
//@ProtoNumber(410) var msg_apply_preview_rsp: Any? = null, //@ProtoNumber(410) var msg_apply_preview_rsp: Any? = null,
//@ProtoNumber(510) var msg_apply_security_strike_rsp: Any? = null, //@ProtoNumber(510) var msg_apply_security_strike_rsp: Any? = null,
) ): Protobuf<Oidb0xfc2RspBody>
@Serializable @Serializable
data class Oidb0xfc2MsgApplyDownloadRsp( data class Oidb0xfc2MsgApplyDownloadRsp(

View File

@ -5,17 +5,18 @@ package protobuf.oidb.cmx0xf57
import kotlinx.serialization.ExperimentalSerializationApi import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoNumber import kotlinx.serialization.protobuf.ProtoNumber
import moe.fuqiuluo.symbols.Protobuf
@Serializable @Serializable
data class Oidb0xf57Req( data class Oidb0xf57Req(
@ProtoNumber(1) val filter: Oidb0xf57Filter, @ProtoNumber(1) val filter: Oidb0xf57Filter,
@ProtoNumber(2) val guildInfo: Oidb0xf57GuildInfo, @ProtoNumber(2) val guildInfo: Oidb0xf57GuildInfo,
) ): Protobuf<Oidb0xf57Req>
@Serializable @Serializable
data class Oidb0xf57Rsp( data class Oidb0xf57Rsp(
@ProtoNumber(1) val metaInfo: Oidb0xf57MetaInfo, @ProtoNumber(1) val metaInfo: Oidb0xf57MetaInfo,
) ): Protobuf<Oidb0xf57Rsp>
@Serializable @Serializable
data class Oidb0xf57MetaInfo( data class Oidb0xf57MetaInfo(

View File

@ -2,12 +2,13 @@ package protobuf.push
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoNumber import kotlinx.serialization.protobuf.ProtoNumber
import moe.fuqiuluo.symbols.Protobuf
@Serializable @Serializable
data class C2CCommonTipsEvent( data class C2CCommonTipsEvent(
@ProtoNumber(7) val params: List<PokeParam>? = null, @ProtoNumber(7) val params: List<PokeParam>? = null,
@ProtoNumber(8) val xmlTips: String? = null, @ProtoNumber(8) val xmlTips: String? = null,
) ): Protobuf<C2CCommonTipsEvent>
@Serializable @Serializable
data class PokeParam( data class PokeParam(

View File

@ -2,11 +2,12 @@ package protobuf.push
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoNumber import kotlinx.serialization.protobuf.ProtoNumber
import moe.fuqiuluo.symbols.Protobuf
@Serializable @Serializable
data class C2CRecallEvent( data class C2CRecallEvent(
@ProtoNumber(1) val head: C2CRecallHead? = null, @ProtoNumber(1) val head: C2CRecallHead? = null,
) ): Protobuf<C2CRecallEvent>
@Serializable @Serializable
data class C2CRecallHead( data class C2CRecallHead(

View File

@ -2,11 +2,12 @@ package protobuf.push
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoNumber import kotlinx.serialization.protobuf.ProtoNumber
import moe.fuqiuluo.symbols.Protobuf
@Serializable @Serializable
data class FriendApplyEvent( data class FriendApplyEvent(
@ProtoNumber(1) val head: FriendApplyHead? = null, @ProtoNumber(1) val head: FriendApplyHead? = null,
) ): Protobuf<FriendApplyEvent>
@Serializable @Serializable

View File

@ -2,10 +2,11 @@ package protobuf.push
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoNumber import kotlinx.serialization.protobuf.ProtoNumber
import moe.fuqiuluo.symbols.Protobuf
@Serializable @Serializable
data class GroupAdminChangeEvent( data class GroupAdminChangeEvent(
@ProtoNumber(1) val groupCode: Long, @ProtoNumber(1) val groupCode: Long,
@ProtoNumber(4) val operation: GroupAdminChangedOperation? = null @ProtoNumber(4) val operation: GroupAdminChangedOperation? = null
) ): Protobuf<GroupAdminChangeEvent>

View File

@ -2,10 +2,11 @@ package protobuf.push
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoNumber import kotlinx.serialization.protobuf.ProtoNumber
import moe.fuqiuluo.symbols.Protobuf
@Serializable @Serializable
data class GroupApplyEvent( data class GroupApplyEvent(
@ProtoNumber(1) val groupCode: Long = Long.MIN_VALUE, @ProtoNumber(1) val groupCode: Long = Long.MIN_VALUE,
@ProtoNumber(3) val applierUid: String = "", @ProtoNumber(3) val applierUid: String = "",
@ProtoNumber(5) val applyMsg: String? = null, @ProtoNumber(5) val applyMsg: String? = null,
) ): Protobuf<GroupApplyEvent>

View File

@ -2,13 +2,14 @@ package protobuf.push
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoNumber import kotlinx.serialization.protobuf.ProtoNumber
import moe.fuqiuluo.symbols.Protobuf
@Serializable @Serializable
data class GroupBanEvent( data class GroupBanEvent(
@ProtoNumber(1) val groupCode: ULong = ULong.MIN_VALUE, @ProtoNumber(1) val groupCode: ULong = ULong.MIN_VALUE,
@ProtoNumber(4) val operatorUid: String = "", @ProtoNumber(4) val operatorUid: String = "",
@ProtoNumber(5) val target: GroupBanTarget? = null, @ProtoNumber(5) val target: GroupBanTarget? = null,
) ): Protobuf<GroupBanEvent>
@Serializable @Serializable
data class GroupBanTarget( data class GroupBanTarget(

View File

@ -2,6 +2,7 @@ package protobuf.push
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoNumber import kotlinx.serialization.protobuf.ProtoNumber
import moe.fuqiuluo.symbols.Protobuf
@Serializable @Serializable
data class GroupCommonTipsEvent( data class GroupCommonTipsEvent(
@ -11,7 +12,7 @@ data class GroupCommonTipsEvent(
@ProtoNumber(26) val baseTips: List<GroupBaseTips>? = null, @ProtoNumber(26) val baseTips: List<GroupBaseTips>? = null,
@ProtoNumber(33) val essenceMsgInfo: List<EssenceMsgInfo>? = null, @ProtoNumber(33) val essenceMsgInfo: List<EssenceMsgInfo>? = null,
@ProtoNumber(37) val msgSeq: ULong = ULong.MIN_VALUE, @ProtoNumber(37) val msgSeq: ULong = ULong.MIN_VALUE,
) ): Protobuf<GroupCommonTipsEvent>
@Serializable @Serializable
data class EssenceMsgInfo( data class EssenceMsgInfo(

View File

@ -2,9 +2,10 @@ package protobuf.push
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoNumber import kotlinx.serialization.protobuf.ProtoNumber
import moe.fuqiuluo.symbols.Protobuf
@Serializable @Serializable
data class GroupInviteEvent( data class GroupInviteEvent(
@ProtoNumber(1) val groupCode: Long, @ProtoNumber(1) val groupCode: Long,
@ProtoNumber(5) val inviterUid: String, @ProtoNumber(5) val inviterUid: String,
) ): Protobuf<GroupInviteEvent>

View File

@ -2,11 +2,12 @@ package protobuf.push
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoNumber import kotlinx.serialization.protobuf.ProtoNumber
import moe.fuqiuluo.symbols.Protobuf
@Serializable @Serializable
data class GroupInvitedApplyEvent( data class GroupInvitedApplyEvent(
@ProtoNumber(2) val applyInfo: GroupInvitedApplyInfo? = null, @ProtoNumber(2) val applyInfo: GroupInvitedApplyInfo? = null,
) ): Protobuf<GroupInvitedApplyEvent>
@Serializable @Serializable
data class GroupInvitedApplyInfo( data class GroupInvitedApplyInfo(

View File

@ -2,6 +2,7 @@ package protobuf.push
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoNumber import kotlinx.serialization.protobuf.ProtoNumber
import moe.fuqiuluo.symbols.Protobuf
@Serializable @Serializable
data class GroupListChangeEvent( data class GroupListChangeEvent(
@ -9,4 +10,4 @@ data class GroupListChangeEvent(
@ProtoNumber(3) val memberUid: String = "", @ProtoNumber(3) val memberUid: String = "",
@ProtoNumber(4) val type: Int = Int.MIN_VALUE, @ProtoNumber(4) val type: Int = Int.MIN_VALUE,
@ProtoNumber(5) val operatorUid: String = "", @ProtoNumber(5) val operatorUid: String = "",
) ): Protobuf<GroupListChangeEvent>

View File

@ -2,13 +2,14 @@ package protobuf.push
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoNumber import kotlinx.serialization.protobuf.ProtoNumber
import moe.fuqiuluo.symbols.Protobuf
import protobuf.message.NtMessage import protobuf.message.NtMessage
@Serializable @Serializable
data class MessagePush( data class MessagePush(
@ProtoNumber(1) val msgBody: NtMessage? = null, @ProtoNumber(1) val msgBody: NtMessage? = null,
@ProtoNumber(4) val clientInfo: MessagePushClientInfo? = null, @ProtoNumber(4) val clientInfo: MessagePushClientInfo? = null,
) ): Protobuf<MessagePush>
@Serializable @Serializable
data class MessagePushClientInfo( data class MessagePushClientInfo(

View File

@ -5,6 +5,7 @@ package protobuf.qweb
import kotlinx.serialization.ExperimentalSerializationApi import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoNumber import kotlinx.serialization.protobuf.ProtoNumber
import moe.fuqiuluo.symbols.Protobuf
@Serializable @Serializable
data class QWebReq( data class QWebReq(
@ -19,7 +20,7 @@ data class QWebReq(
//@ProtoNumber(9) var Crypto: Any? = null, //@ProtoNumber(9) var Crypto: Any? = null,
@ProtoNumber(10) var extinfo: List<QWebExtInfo>? = null, @ProtoNumber(10) var extinfo: List<QWebExtInfo>? = null,
//@ProtoNumber(11) var contentType: Any? = null, //@ProtoNumber(11) var contentType: Any? = null,
) ): Protobuf<QWebReq>
@Serializable @Serializable
data class QWebExtInfo( data class QWebExtInfo(
@ -34,4 +35,4 @@ data class QWebRsp(
//@ProtoNumber(3) var errMsg: String? = null, //@ProtoNumber(3) var errMsg: String? = null,
@ProtoNumber(4) var buffer: ByteArray? = null, @ProtoNumber(4) var buffer: ByteArray? = null,
//@ProtoNumber(5) var Extinfo: List<QWebExtInfo>? = null, //@ProtoNumber(5) var Extinfo: List<QWebExtInfo>? = null,
) ): Protobuf<QWebRsp>

View File

@ -19,7 +19,7 @@ import kotlinx.coroutines.launch
import kotlinx.coroutines.suspendCancellableCoroutine import kotlinx.coroutines.suspendCancellableCoroutine
import kotlinx.coroutines.withTimeoutOrNull import kotlinx.coroutines.withTimeoutOrNull
import kotlinx.serialization.encodeToByteArray import kotlinx.serialization.encodeToByteArray
import kotlinx.serialization.protobuf.ProtoBuf
import moe.fuqiuluo.shamrock.tools.slice import moe.fuqiuluo.shamrock.tools.slice
import moe.fuqiuluo.shamrock.utils.DeflateTools import moe.fuqiuluo.shamrock.utils.DeflateTools
import moe.fuqiuluo.shamrock.utils.PlatformUtils import moe.fuqiuluo.shamrock.utils.PlatformUtils
@ -28,6 +28,7 @@ import moe.fuqiuluo.shamrock.xposed.helper.internal.DynamicReceiver
import moe.fuqiuluo.shamrock.xposed.helper.internal.IPCRequest import moe.fuqiuluo.shamrock.xposed.helper.internal.IPCRequest
import protobuf.oidb.TrpcOidb import protobuf.oidb.TrpcOidb
import mqq.app.MobileQQ import mqq.app.MobileQQ
import protobuf.auto.toByteArray
import tencent.im.oidb.oidb_sso import tencent.im.oidb.oidb_sso
import kotlin.coroutines.CoroutineContext import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.resume import kotlin.coroutines.resume
@ -129,7 +130,7 @@ internal abstract class BaseSvc {
buffer = buffer, buffer = buffer,
flag = 0 flag = 0
) )
to.putWupBuffer(ProtoBuf.encodeToByteArray(oidb)) to.putWupBuffer(oidb.toByteArray())
to.addAttribute("req_pb_protocol_flag", true) to.addAttribute("req_pb_protocol_flag", true)
if (seq != -1) { if (seq != -1) {

View File

@ -1,21 +1,20 @@
package moe.fuqiuluo.qqinterface.servlet package moe.fuqiuluo.qqinterface.servlet
import kotlinx.serialization.encodeToByteArray import kotlinx.serialization.encodeToByteArray
import kotlinx.serialization.protobuf.ProtoBuf import protobuf.auto.toByteArray
import protobuf.oidb.cmd0x9082.Oidb0x9082 import protobuf.oidb.cmd0x9082.Oidb0x9082
internal object ChatSvc: BaseSvc() { internal object ChatSvc: BaseSvc() {
fun setGroupMessageCommentFace(peer: Long, msgSeq: ULong, faceIndex: String, isSet: Boolean) { fun setGroupMessageCommentFace(peer: Long, msgSeq: ULong, faceIndex: String, isSet: Boolean) {
val serviceId = if (isSet) 1 else 2 val serviceId = if (isSet) 1 else 2
sendOidb("OidbSvcTrpcTcp.0x9082_$serviceId", 36994, serviceId, ProtoBuf.encodeToByteArray( sendOidb("OidbSvcTrpcTcp.0x9082_$serviceId", 36994, serviceId, Oidb0x9082(
Oidb0x9082(
peer = peer.toULong(), peer = peer.toULong(),
msgSeq = msgSeq, msgSeq = msgSeq,
faceIndex = faceIndex, faceIndex = faceIndex,
flag = 1u, flag = 1u,
u1 = 0u, u1 = 0u,
u2 = 0u u2 = 0u
) ).toByteArray())
))
} }
} }

View File

@ -1,9 +1,6 @@
package moe.fuqiuluo.qqinterface.servlet package moe.fuqiuluo.qqinterface.servlet
import com.tencent.mobileqq.pb.ByteStringMicro import com.tencent.mobileqq.pb.ByteStringMicro
import kotlinx.serialization.decodeFromByteArray
import kotlinx.serialization.encodeToByteArray
import kotlinx.serialization.protobuf.ProtoBuf
import moe.fuqiuluo.qqinterface.servlet.structures.* import moe.fuqiuluo.qqinterface.servlet.structures.*
import moe.fuqiuluo.qqinterface.servlet.transfile.RichProtoSvc import moe.fuqiuluo.qqinterface.servlet.transfile.RichProtoSvc
import moe.fuqiuluo.shamrock.helper.Level import moe.fuqiuluo.shamrock.helper.Level
@ -12,6 +9,8 @@ import moe.fuqiuluo.shamrock.tools.EMPTY_BYTE_ARRAY
import moe.fuqiuluo.shamrock.tools.slice import moe.fuqiuluo.shamrock.tools.slice
import moe.fuqiuluo.shamrock.tools.toHexString import moe.fuqiuluo.shamrock.tools.toHexString
import moe.fuqiuluo.shamrock.utils.DeflateTools import moe.fuqiuluo.shamrock.utils.DeflateTools
import moe.fuqiuluo.symbols.decode
import moe.fuqiuluo.symbols.decodeProtobuf
import protobuf.oidb.cmd0x6d7.CreateFolderReq import protobuf.oidb.cmd0x6d7.CreateFolderReq
import protobuf.oidb.cmd0x6d7.DeleteFolderReq import protobuf.oidb.cmd0x6d7.DeleteFolderReq
import protobuf.oidb.cmd0x6d7.MoveFolderReq import protobuf.oidb.cmd0x6d7.MoveFolderReq
@ -22,24 +21,25 @@ import tencent.im.oidb.cmd0x6d6.oidb_0x6d6
import tencent.im.oidb.cmd0x6d8.oidb_0x6d8 import tencent.im.oidb.cmd0x6d8.oidb_0x6d8
import tencent.im.oidb.oidb_sso import tencent.im.oidb.oidb_sso
import protobuf.group_file_common.FolderInfo as GroupFileCommonFolderInfo import protobuf.group_file_common.FolderInfo as GroupFileCommonFolderInfo
import protobuf.auto.toByteArray
internal object FileSvc: BaseSvc() { internal object FileSvc: BaseSvc() {
suspend fun createFileFolder(groupId: String, folderName: String, parentFolderId: String = "/"): Result<GroupFileCommonFolderInfo> { suspend fun createFileFolder(groupId: String, folderName: String, parentFolderId: String = "/"): Result<GroupFileCommonFolderInfo> {
val data = ProtoBuf.encodeToByteArray( val data = Oidb0x6d7ReqBody(
Oidb0x6d7ReqBody(
createFolder = CreateFolderReq( createFolder = CreateFolderReq(
groupCode = groupId.toULong(), groupCode = groupId.toULong(),
appId = 3u, appId = 3u,
parentFolderId = parentFolderId, parentFolderId = parentFolderId,
folderName = folderName folderName = folderName
) )
) ).toByteArray()
)
val resultBuffer = sendOidbAW("OidbSvc.0x6d7_0", 1751, 0, data) val resultBuffer = sendOidbAW("OidbSvc.0x6d7_0", 1751, 0, data)
?: return Result.failure(Exception("unable to fetch result")) ?: return Result.failure(Exception("unable to fetch result"))
val oidbPkg = oidb_sso.OIDBSSOPkg() val oidbPkg = oidb_sso.OIDBSSOPkg()
oidbPkg.mergeFrom(resultBuffer.slice(4)) oidbPkg.mergeFrom(resultBuffer.slice(4))
val rsp = ProtoBuf.decodeFromByteArray<Oidb0x6d7RespBody>(oidbPkg.bytes_bodybuffer.get().toByteArray()) val rsp = oidbPkg.bytes_bodybuffer.get()
.toByteArray()
.decodeProtobuf<Oidb0x6d7RespBody>()
if (rsp.createFolder?.retCode != 0) { if (rsp.createFolder?.retCode != 0) {
return Result.failure(Exception("unable to create folder: ${rsp.createFolder?.retCode}")) return Result.failure(Exception("unable to create folder: ${rsp.createFolder?.retCode}"))
} }
@ -47,52 +47,46 @@ internal object FileSvc: BaseSvc() {
} }
suspend fun deleteGroupFolder(groupId: String, folderUid: String): Boolean { suspend fun deleteGroupFolder(groupId: String, folderUid: String): Boolean {
val buffer = sendOidbAW("OidbSvc.0x6d7_1", 1751, 1, ProtoBuf.encodeToByteArray( val buffer = sendOidbAW("OidbSvc.0x6d7_1", 1751, 1, Oidb0x6d7ReqBody(
Oidb0x6d7ReqBody(
deleteFolder = DeleteFolderReq( deleteFolder = DeleteFolderReq(
groupCode = groupId.toULong(), groupCode = groupId.toULong(),
appId = 3u, appId = 3u,
folderId = folderUid folderId = folderUid
) )
) ).toByteArray()) ?: return false
)) ?: return false
val oidbPkg = oidb_sso.OIDBSSOPkg() val oidbPkg = oidb_sso.OIDBSSOPkg()
oidbPkg.mergeFrom(buffer.slice(4)) oidbPkg.mergeFrom(buffer.slice(4))
val rsp = ProtoBuf.decodeFromByteArray<Oidb0x6d7RespBody>(oidbPkg.bytes_bodybuffer.get().toByteArray()) val rsp = oidbPkg.bytes_bodybuffer.get().toByteArray().decodeProtobuf<Oidb0x6d7RespBody>()
return rsp.deleteFolder?.retCode == 0 return rsp.deleteFolder?.retCode == 0
} }
suspend fun moveGroupFolder(groupId: String, folderUid: String, newParentFolderUid: String): Boolean { suspend fun moveGroupFolder(groupId: String, folderUid: String, newParentFolderUid: String): Boolean {
val buffer = sendOidbAW("OidbSvc.0x6d7_2", 1751, 2, ProtoBuf.encodeToByteArray( val buffer = sendOidbAW("OidbSvc.0x6d7_2", 1751, 2, Oidb0x6d7ReqBody(
Oidb0x6d7ReqBody(
moveFolder = MoveFolderReq( moveFolder = MoveFolderReq(
groupCode = groupId.toULong(), groupCode = groupId.toULong(),
appId = 3u, appId = 3u,
folderId = folderUid, folderId = folderUid,
parentFolderId = "/" parentFolderId = "/"
) )
) ).toByteArray()) ?: return false
)) ?: return false
val oidbPkg = oidb_sso.OIDBSSOPkg() val oidbPkg = oidb_sso.OIDBSSOPkg()
oidbPkg.mergeFrom(buffer.slice(4)) oidbPkg.mergeFrom(buffer.slice(4))
val rsp = ProtoBuf.decodeFromByteArray<Oidb0x6d7RespBody>(oidbPkg.bytes_bodybuffer.get().toByteArray()) val rsp = oidbPkg.bytes_bodybuffer.get().toByteArray().decodeProtobuf<Oidb0x6d7RespBody>()
return rsp.moveFolder?.retCode == 0 return rsp.moveFolder?.retCode == 0
} }
suspend fun renameFolder(groupId: String, folderUid: String, name: String): Boolean { suspend fun renameFolder(groupId: String, folderUid: String, name: String): Boolean {
val buffer = sendOidbAW("OidbSvc.0x6d7_3", 1751, 3, ProtoBuf.encodeToByteArray( val buffer = sendOidbAW("OidbSvc.0x6d7_3", 1751, 3, Oidb0x6d7ReqBody(
Oidb0x6d7ReqBody(
renameFolder = RenameFolderReq( renameFolder = RenameFolderReq(
groupCode = groupId.toULong(), groupCode = groupId.toULong(),
appId = 3u, appId = 3u,
folderId = folderUid, folderId = folderUid,
folderName = name folderName = name
) )
) ).toByteArray()) ?: return false
)) ?: return false
val oidbPkg = oidb_sso.OIDBSSOPkg() val oidbPkg = oidb_sso.OIDBSSOPkg()
oidbPkg.mergeFrom(buffer.slice(4)) oidbPkg.mergeFrom(buffer.slice(4))
val rsp = ProtoBuf.decodeFromByteArray<Oidb0x6d7RespBody>(oidbPkg.bytes_bodybuffer.get().toByteArray()) val rsp = oidbPkg.bytes_bodybuffer.get().toByteArray().decodeProtobuf<Oidb0x6d7RespBody>()
return rsp.renameFolder?.retCode == 0 return rsp.renameFolder?.retCode == 0
} }

View File

@ -7,14 +7,10 @@ import com.tencent.qqnt.kernel.nativeinterface.GProGuildRole
import com.tencent.qqnt.kernel.nativeinterface.GProRoleCreateInfo import com.tencent.qqnt.kernel.nativeinterface.GProRoleCreateInfo
import com.tencent.qqnt.kernel.nativeinterface.GProRoleMemberList import com.tencent.qqnt.kernel.nativeinterface.GProRoleMemberList
import com.tencent.qqnt.kernel.nativeinterface.GProRolePermission import com.tencent.qqnt.kernel.nativeinterface.GProRolePermission
import io.ktor.utils.io.ByteReadChannel
import io.ktor.utils.io.core.readBytes
import kotlinx.coroutines.suspendCancellableCoroutine import kotlinx.coroutines.suspendCancellableCoroutine
import kotlinx.coroutines.withTimeoutOrNull import kotlinx.coroutines.withTimeoutOrNull
import kotlinx.serialization.ExperimentalSerializationApi import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.decodeFromByteArray
import kotlinx.serialization.encodeToByteArray
import kotlinx.serialization.protobuf.ProtoBuf
import moe.fuqiuluo.qqinterface.servlet.structures.GProChannelInfo import moe.fuqiuluo.qqinterface.servlet.structures.GProChannelInfo
import moe.fuqiuluo.qqinterface.servlet.structures.GetGuildMemberListNextToken import moe.fuqiuluo.qqinterface.servlet.structures.GetGuildMemberListNextToken
import moe.fuqiuluo.qqinterface.servlet.structures.GuildInfo import moe.fuqiuluo.qqinterface.servlet.structures.GuildInfo
@ -24,10 +20,11 @@ import moe.fuqiuluo.shamrock.helper.Level
import moe.fuqiuluo.shamrock.helper.LogCenter import moe.fuqiuluo.shamrock.helper.LogCenter
import moe.fuqiuluo.shamrock.tools.EMPTY_BYTE_ARRAY import moe.fuqiuluo.shamrock.tools.EMPTY_BYTE_ARRAY
import moe.fuqiuluo.shamrock.tools.slice import moe.fuqiuluo.shamrock.tools.slice
import moe.fuqiuluo.shamrock.tools.toHexString
import moe.fuqiuluo.shamrock.utils.DeflateTools
import moe.fuqiuluo.shamrock.utils.PlatformUtils import moe.fuqiuluo.shamrock.utils.PlatformUtils
import moe.fuqiuluo.shamrock.xposed.helper.NTServiceFetcher import moe.fuqiuluo.shamrock.xposed.helper.NTServiceFetcher
import moe.fuqiuluo.symbols.decode
import moe.fuqiuluo.symbols.decodeProtobuf
import protobuf.auto.toByteArray
import protobuf.guild.GetGuildFeedsReq import protobuf.guild.GetGuildFeedsReq
import protobuf.guild.GetGuildFeedsRsp import protobuf.guild.GetGuildFeedsRsp
import protobuf.oidb.cmd0xf88.GProFilter import protobuf.oidb.cmd0xf88.GProFilter
@ -54,33 +51,31 @@ internal object GProSvc: BaseSvc() {
} }
suspend fun getGuildInfo(guildId: ULong): Result<Oidb0xf57MetaInfo> { suspend fun getGuildInfo(guildId: ULong): Result<Oidb0xf57MetaInfo> {
val respBuffer = sendOidbAW("OidbSvcTrpcTcp.0xf57_9", 0xf57, 9, ProtoBuf.encodeToByteArray( val respBuffer = sendOidbAW("OidbSvcTrpcTcp.0xf57_9", 0xf57, 9, Oidb0xf57Req(
Oidb0xf57Req(
filter = Oidb0xf57Filter( filter = Oidb0xf57Filter(
u1 = Oidb0xf57U1(1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u), u1 = Oidb0xf57U1(1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u),
u2 = Oidb0xf57U2(1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u) u2 = Oidb0xf57U2(1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u)
), ),
guildInfo = Oidb0xf57GuildInfo(guildId = guildId) guildInfo = Oidb0xf57GuildInfo(guildId = guildId)
) ).toByteArray())
))
val body = oidb_sso.OIDBSSOPkg() val body = oidb_sso.OIDBSSOPkg()
if (respBuffer == null) { if (respBuffer == null) {
return Result.failure(Exception("unable to send packet")) return Result.failure(Exception("unable to send packet"))
} }
body.mergeFrom(respBuffer.slice(4)) body.mergeFrom(respBuffer.slice(4))
return runCatching { return runCatching {
ProtoBuf.decodeFromByteArray<Oidb0xf57Rsp>( body.bytes_bodybuffer.get()
body.bytes_bodybuffer.get().toByteArray() .toByteArray()
).metaInfo .decodeProtobuf<Oidb0xf57Rsp>().metaInfo
} }
} }
suspend fun getGuildFeeds(guildId: ULong, channelId: ULong, startIndex: Int): Result<GetGuildFeedsRsp> { suspend fun getGuildFeeds(guildId: ULong, channelId: ULong, startIndex: Int): Result<GetGuildFeedsRsp> {
val buffer = sendBufferAW("QChannelSvr.trpc.qchannel.commreader.ComReader.GetGuildFeeds", true, ProtoBuf.encodeToByteArray(QWebReq( val buffer = sendBufferAW("QChannelSvr.trpc.qchannel.commreader.ComReader.GetGuildFeeds", true, QWebReq(
seq = 10, seq = 10,
qua = PlatformUtils.getQUA(), qua = PlatformUtils.getQUA(),
deviceInfo = "i=&imsi=&mac=02:00:00:00:00:00&m=Shamrock&o=114514&a=1919810&sd=0&c64=1&sc=1&p=8000*8000&aid=123456789012345678901234567890abcdef&f=Tencent&mm=5610&cf=1726&cc=8&qimei=&qimei36=&sharpP=1&n=nether_world&support_xsj_live=false&client_mod=concise&timezone=America/La_Paz&material_sdk_version=&vh265=&refreshrate=10086&hwlevel=9&suphdr=1&is_teenager_mod=8&liveH265=&bmst=5&AV1=0", deviceInfo = "i=&imsi=&mac=02:00:00:00:00:00&m=Shamrock&o=114514&a=1919810&sd=0&c64=1&sc=1&p=8000*8000&aid=123456789012345678901234567890abcdef&f=Tencent&mm=5610&cf=1726&cc=8&qimei=&qimei36=&sharpP=1&n=nether_world&support_xsj_live=false&client_mod=concise&timezone=America/La_Paz&material_sdk_version=&vh265=&refreshrate=10086&hwlevel=9&suphdr=1&is_teenager_mod=8&liveH265=&bmst=5&AV1=0",
buffer = ProtoBuf.encodeToByteArray(GetGuildFeedsReq( buffer = GetGuildFeedsReq(
count = 12, count = 12,
from = startIndex, from = startIndex,
feedAttchInfo = EMPTY_BYTE_ARRAY, feedAttchInfo = EMPTY_BYTE_ARRAY,
@ -89,18 +84,18 @@ internal object GProSvc: BaseSvc() {
u7 = 0, u7 = 0,
u8 = 1, u8 = 1,
u9 = EMPTY_BYTE_ARRAY u9 = EMPTY_BYTE_ARRAY
)), ).toByteArray(),
traceId = app.account + "_0_0", traceId = app.account + "_0_0",
extinfo = listOf( extinfo = listOf(
QWebExtInfo("fc-appid", "96"), QWebExtInfo("fc-appid", "96"),
QWebExtInfo("environment_id", "shamrock"), QWebExtInfo("environment_id", "shamrock"),
QWebExtInfo("tiny_id", getSelfTinyId().toString()), QWebExtInfo("tiny_id", getSelfTinyId().toString()),
) )
))) ?: return Result.failure(Exception("unable to send packet")) ).toByteArray()) ?: return Result.failure(Exception("unable to send packet"))
val webRsp = ProtoBuf.decodeFromByteArray<QWebRsp>(buffer.slice(4)) val webRsp = buffer.slice(4).decodeProtobuf<QWebRsp>()
if(webRsp.buffer == null) return Result.failure(Exception("server error")) if(webRsp.buffer == null) return Result.failure(Exception("server error"))
val wupBuffer = webRsp.buffer!! val wupBuffer = webRsp.buffer!!
val feeds = ProtoBuf.decodeFromByteArray<GetGuildFeedsRsp>(wupBuffer) val feeds = wupBuffer.decodeProtobuf<GetGuildFeedsRsp>()
return Result.success(feeds) return Result.success(feeds)
} }
@ -188,23 +183,19 @@ internal object GProSvc: BaseSvc() {
guildId: ULong, guildId: ULong,
memberTinyId: ULong memberTinyId: ULong
): Result<GProUserInfo> { ): Result<GProUserInfo> {
val respBuffer = sendOidbAW("OidbSvcTrpcTcp.0xf88_1", 0xf88, 1, ProtoBuf.encodeToByteArray( val respBuffer = sendOidbAW("OidbSvcTrpcTcp.0xf88_1", 0xf88, 1, Oidb0xf88Req(
Oidb0xf88Req(
filter = GProFilter(1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u), filter = GProFilter(1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u),
memberId = 0uL, memberId = 0uL,
tinyId = memberTinyId, tinyId = memberTinyId,
guildId = guildId guildId = guildId
) ).toByteArray())
))
val body = oidb_sso.OIDBSSOPkg() val body = oidb_sso.OIDBSSOPkg()
if (respBuffer == null) { if (respBuffer == null) {
return Result.failure(Exception("unable to send packet")) return Result.failure(Exception("unable to send packet"))
} }
body.mergeFrom(respBuffer.slice(4)) body.mergeFrom(respBuffer.slice(4))
return runCatching { return runCatching {
ProtoBuf.decodeFromByteArray<Oidb0xf88Rsp>( body.bytes_bodybuffer.get().toByteArray().decodeProtobuf<Oidb0xf88Rsp>().userInfo!!
body.bytes_bodybuffer.get().toByteArray()
).userInfo!!
} }
} }

View File

@ -46,7 +46,7 @@ import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonElement import kotlinx.serialization.json.JsonElement
import kotlinx.serialization.json.decodeFromStream import kotlinx.serialization.json.decodeFromStream
import kotlinx.serialization.json.jsonObject import kotlinx.serialization.json.jsonObject
import kotlinx.serialization.protobuf.ProtoBuf
import moe.fuqiuluo.qqinterface.servlet.TicketSvc.getLongUin import moe.fuqiuluo.qqinterface.servlet.TicketSvc.getLongUin
import moe.fuqiuluo.qqinterface.servlet.TicketSvc.getUin import moe.fuqiuluo.qqinterface.servlet.TicketSvc.getUin
import moe.fuqiuluo.qqinterface.servlet.structures.GroupAtAllRemainInfo import moe.fuqiuluo.qqinterface.servlet.structures.GroupAtAllRemainInfo
@ -78,6 +78,7 @@ import moe.fuqiuluo.shamrock.xposed.helper.NTServiceFetcher
import protobuf.oidb.cmd0xf16.Oidb0xf16 import protobuf.oidb.cmd0xf16.Oidb0xf16
import protobuf.oidb.cmd0xf16.SetGroupRemarkReq import protobuf.oidb.cmd0xf16.SetGroupRemarkReq
import mqq.app.MobileQQ import mqq.app.MobileQQ
import protobuf.auto.toByteArray
import tencent.im.group.group_member_info import tencent.im.group.group_member_info
import tencent.im.oidb.cmd0x88d.oidb_0x88d import tencent.im.oidb.cmd0x88d.oidb_0x88d
import tencent.im.oidb.cmd0x899.oidb_0x899 import tencent.im.oidb.cmd0x899.oidb_0x899
@ -274,15 +275,13 @@ internal object GroupSvc: BaseSvc() {
} }
fun modifyGroupRemark(groupId: Long, remark: String): Boolean { fun modifyGroupRemark(groupId: Long, remark: String): Boolean {
sendOidb("OidbSvc.0xf16_1", 3862, 1, ProtoBuf.encodeToByteArray( sendOidb("OidbSvc.0xf16_1", 3862, 1, Oidb0xf16(
Oidb0xf16(
setGroupRemarkReq = SetGroupRemarkReq( setGroupRemarkReq = SetGroupRemarkReq(
groupCode = groupId.toULong(), groupCode = groupId.toULong(),
groupUin = groupCode2GroupUin(groupId).toULong(), groupUin = groupCode2GroupUin(groupId).toULong(),
groupRemark = remark groupRemark = remark
) )
) ).toByteArray())
))
return true return true
} }

View File

@ -11,10 +11,8 @@ import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import kotlinx.coroutines.suspendCancellableCoroutine import kotlinx.coroutines.suspendCancellableCoroutine
import kotlinx.coroutines.withTimeoutOrNull import kotlinx.coroutines.withTimeoutOrNull
import kotlinx.serialization.decodeFromByteArray
import kotlinx.serialization.encodeToByteArray
import kotlinx.serialization.json.JsonArray import kotlinx.serialization.json.JsonArray
import kotlinx.serialization.protobuf.ProtoBuf
import moe.fuqiuluo.qqinterface.servlet.msg.messageelement.toSegments import moe.fuqiuluo.qqinterface.servlet.msg.messageelement.toSegments
import moe.fuqiuluo.qqinterface.servlet.msg.toListMap import moe.fuqiuluo.qqinterface.servlet.msg.toListMap
import moe.fuqiuluo.shamrock.helper.ContactHelper import moe.fuqiuluo.shamrock.helper.ContactHelper
@ -28,6 +26,9 @@ import moe.fuqiuluo.shamrock.tools.*
import moe.fuqiuluo.shamrock.utils.DeflateTools import moe.fuqiuluo.shamrock.utils.DeflateTools
import moe.fuqiuluo.shamrock.xposed.helper.NTServiceFetcher import moe.fuqiuluo.shamrock.xposed.helper.NTServiceFetcher
import moe.fuqiuluo.shamrock.xposed.helper.msgService import moe.fuqiuluo.shamrock.xposed.helper.msgService
import moe.fuqiuluo.symbols.decode
import moe.fuqiuluo.symbols.decodeProtobuf
import protobuf.auto.toByteArray
import protobuf.message.longmsg.* import protobuf.message.longmsg.*
import kotlin.coroutines.resume import kotlin.coroutines.resume
import kotlin.coroutines.suspendCoroutine import kotlin.coroutines.suspendCoroutine
@ -239,14 +240,14 @@ internal object MsgSvc : BaseSvc() {
) )
) )
) )
LogCenter.log(ProtoBuf.encodeToByteArray(payload).toHexString(), Level.DEBUG) LogCenter.log(payload.toByteArray().toHexString(), Level.DEBUG)
val req = LongMsgReq( val req = LongMsgReq(
sendInfo = SendLongMsgInfo( sendInfo = SendLongMsgInfo(
type = if (groupUin == null) 1 else 3, type = if (groupUin == null) 1 else 3,
uid = LongMsgUid(groupUin ?: uid), uid = LongMsgUid(groupUin ?: uid),
groupUin = groupUin?.toInt(), groupUin = groupUin?.toInt(),
payload = DeflateTools.gzip(ProtoBuf.encodeToByteArray(payload)) payload = DeflateTools.gzip(payload.toByteArray())
), ),
setting = LongMsgSettings( setting = LongMsgSettings(
field1 = 4, field1 = 4,
@ -258,9 +259,9 @@ internal object MsgSvc : BaseSvc() {
val buffer = sendBufferAW( val buffer = sendBufferAW(
"trpc.group.long_msg_interface.MsgService.SsoSendLongMsg", "trpc.group.long_msg_interface.MsgService.SsoSendLongMsg",
true, true,
ProtoBuf.encodeToByteArray(req) req.toByteArray()
) ?: return Result.failure(Exception("unable to upload multi message")) ) ?: return Result.failure(Exception("unable to upload multi message"))
val rsp = ProtoBuf.decodeFromByteArray<LongMsgRsp>(buffer.slice(4)) val rsp = buffer.slice(4).decodeProtobuf<LongMsgRsp>()
return rsp.sendResult?.resId?.let { Result.success(it) } return rsp.sendResult?.resId?.let { Result.success(it) }
?: Result.failure(Exception("unable to upload multi message")) ?: Result.failure(Exception("unable to upload multi message"))
} }
@ -282,14 +283,14 @@ internal object MsgSvc : BaseSvc() {
val buffer = sendBufferAW( val buffer = sendBufferAW(
"trpc.group.long_msg_interface.MsgService.SsoRecvLongMsg", "trpc.group.long_msg_interface.MsgService.SsoRecvLongMsg",
true, true,
ProtoBuf.encodeToByteArray(req) req.toByteArray()
) ?: return Result.failure(Exception("unable to get multi message")) ) ?: return Result.failure(Exception("unable to get multi message"))
val rsp = ProtoBuf.decodeFromByteArray<LongMsgRsp>(buffer.slice(4)) val rsp = buffer.slice(4).decodeProtobuf<LongMsgRsp>()
val zippedPayload = DeflateTools.ungzip( val zippedPayload = DeflateTools.ungzip(
rsp.recvResult?.payload ?: return Result.failure(Exception("unable to get multi message")) rsp.recvResult?.payload ?: return Result.failure(Exception("unable to get multi message"))
) )
LogCenter.log(zippedPayload.toHexString(), Level.DEBUG) LogCenter.log(zippedPayload.toHexString(), Level.DEBUG)
val payload = ProtoBuf.decodeFromByteArray<LongMsgPayload>(zippedPayload) val payload = zippedPayload.decodeProtobuf<LongMsgPayload>()
payload.action?.forEach { payload.action?.forEach {
if (it.command == "MultiMsg") { if (it.command == "MultiMsg") {
return Result.success(it.data?.body?.map { msg -> return Result.success(it.data?.body?.map { msg ->

View File

@ -10,7 +10,7 @@ import io.ktor.utils.io.core.writeInt
import kotlinx.coroutines.suspendCancellableCoroutine import kotlinx.coroutines.suspendCancellableCoroutine
import kotlinx.coroutines.withTimeoutOrNull import kotlinx.coroutines.withTimeoutOrNull
import kotlinx.serialization.encodeToByteArray import kotlinx.serialization.encodeToByteArray
import kotlinx.serialization.protobuf.ProtoBuf
import moe.fuqiuluo.shamrock.remote.action.handlers.GetHistoryMsg import moe.fuqiuluo.shamrock.remote.action.handlers.GetHistoryMsg
import moe.fuqiuluo.shamrock.remote.service.listener.AioListener import moe.fuqiuluo.shamrock.remote.service.listener.AioListener
import moe.fuqiuluo.shamrock.tools.broadcast import moe.fuqiuluo.shamrock.tools.broadcast
@ -24,6 +24,7 @@ import protobuf.message.MessageHead
import protobuf.message.MessageBody import protobuf.message.MessageBody
import protobuf.push.MessagePush import protobuf.push.MessagePush
import mqq.app.MobileQQ import mqq.app.MobileQQ
import protobuf.auto.toByteArray
import kotlin.coroutines.resume import kotlin.coroutines.resume
internal object PacketSvc: BaseSvc() { internal object PacketSvc: BaseSvc() {
@ -77,7 +78,7 @@ internal object PacketSvc: BaseSvc() {
) )
) )
fakeReceive("trpc.msg.olpush.OlPushService.MsgPush", 10000, ProtoBuf.encodeToByteArray(msgPush)) fakeReceive("trpc.msg.olpush.OlPushService.MsgPush", 10000, msgPush.toByteArray())
return withTimeoutOrNull(5000L) { return withTimeoutOrNull(5000L) {
suspendCancellableCoroutine { suspendCancellableCoroutine {
AioListener.registerTemporaryMsgListener(msgSeq) { AioListener.registerTemporaryMsgListener(msgSeq) {

View File

@ -15,7 +15,7 @@ import kotlinx.io.core.readBytes
import kotlinx.io.core.writeFully import kotlinx.io.core.writeFully
import kotlinx.serialization.ExperimentalSerializationApi import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.encodeToByteArray import kotlinx.serialization.encodeToByteArray
import kotlinx.serialization.protobuf.ProtoBuf
import moe.fuqiuluo.shamrock.helper.Level import moe.fuqiuluo.shamrock.helper.Level
import moe.fuqiuluo.shamrock.helper.LogCenter import moe.fuqiuluo.shamrock.helper.LogCenter
import moe.fuqiuluo.shamrock.tools.hex2ByteArray import moe.fuqiuluo.shamrock.tools.hex2ByteArray
@ -39,6 +39,7 @@ import mqq.manager.TicketManager
import oicq.wlogin_sdk.request.Ticket import oicq.wlogin_sdk.request.Ticket
import oicq.wlogin_sdk.request.WtTicketPromise import oicq.wlogin_sdk.request.WtTicketPromise
import oicq.wlogin_sdk.tools.ErrMsg import oicq.wlogin_sdk.tools.ErrMsg
import protobuf.auto.toByteArray
import java.io.ByteArrayOutputStream import java.io.ByteArrayOutputStream
import java.io.File import java.io.File
import java.nio.ByteBuffer import java.nio.ByteBuffer
@ -329,9 +330,9 @@ internal object QFavSvc: BaseSvc() {
} }
val pSKey = getWeiYunPSKey() val pSKey = getWeiYunPSKey()
httpNetReq.mHttpMethod = HttpNetReq.HTTP_POST httpNetReq.mHttpMethod = HttpNetReq.HTTP_POST
httpNetReq.mSendData = DeflateTools.gzip(packData(packHead(cmd, pSKey), ProtoBuf.encodeToByteArray( httpNetReq.mSendData = DeflateTools.gzip(packData(packHead(cmd, pSKey), WeiyunComm(
WeiyunComm(req = req) req = req
))) ).toByteArray()))
httpNetReq.mOutStream = outputStream httpNetReq.mOutStream = outputStream
httpNetReq.mStartDownOffset = 0L httpNetReq.mStartDownOffset = 0L
httpNetReq.mReqProperties["Shamrock"] = "true" httpNetReq.mReqProperties["Shamrock"] = "true"
@ -351,8 +352,7 @@ internal object QFavSvc: BaseSvc() {
} }
private fun packHead(cmd: Int, pskey: String): ByteArray { private fun packHead(cmd: Int, pskey: String): ByteArray {
return ProtoBuf.encodeToByteArray( return WeiyunMsgHead(
WeiyunMsgHead(
uin = app.longAccountUin.toULong(), uin = app.longAccountUin.toULong(),
seq = seq++.toUInt(), seq = seq++.toUInt(),
type = 1u, type = 1u,
@ -364,8 +364,7 @@ internal object QFavSvc: BaseSvc() {
key = pskey.toByteArray(), key = pskey.toByteArray(),
majorVersion = MAJOR_VERSION.toUInt(), majorVersion = MAJOR_VERSION.toUInt(),
minorVersion = MINOR_VERSION.toUInt(), minorVersion = MINOR_VERSION.toUInt(),
) ).toByteArray()
)
} }
private fun packData(head: ByteArray, body: ByteArray): ByteArray { private fun packData(head: ByteArray, body: ByteArray): ByteArray {

View File

@ -26,4 +26,12 @@ sealed class ArkAppInfo(
signature = "7194d531cbe7960a22007b9f6bdaa38b", signature = "7194d531cbe7960a22007b9f6bdaa38b",
miniAppId = 1109937557 miniAppId = 1109937557
) )
data object Docs: ArkAppInfo(
appId = 0,
version = "0.0.0",
packageName = "",
signature = "f3da3147654d9a21f3237b88f20dce9c",
miniAppId = 1108338344
)
} }

View File

@ -53,6 +53,7 @@ internal object ArkMsgSvc: BaseSvc() {
sendOidb("OidbSvc.0xb77_9", 0xb77, 9, req.toByteArray()) sendOidb("OidbSvc.0xb77_9", 0xb77, 9, req.toByteArray())
} }
/*
suspend fun tryShareJsonMessage( suspend fun tryShareJsonMessage(
jsonString: String, jsonString: String,
arkAppInfo: ArkAppInfo = ArkAppInfo.DanMaKu, arkAppInfo: ArkAppInfo = ArkAppInfo.DanMaKu,
@ -96,5 +97,5 @@ internal object ArkMsgSvc: BaseSvc() {
} }
} ?: return Result.failure(Exception("unable to sign json")) } ?: return Result.failure(Exception("unable to sign json"))
return Result.success(signedJson) return Result.success(signedJson)
} }*/
} }

View File

@ -0,0 +1,9 @@
package moe.fuqiuluo.qqinterface.servlet.ark
import moe.fuqiuluo.qqinterface.servlet.BaseSvc
internal object LightAppSvc: BaseSvc() {
suspend fun adaptShare() {
}
}

View File

@ -2,6 +2,7 @@ package moe.fuqiuluo.qqinterface.servlet.structures
import kotlinx.serialization.SerialName import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import moe.fuqiuluo.symbols.Protobuf
@Serializable @Serializable
data class GuildInfo( data class GuildInfo(
@ -59,7 +60,7 @@ data class GetGuildMemberListNextToken(
@SerialName("role_index") val roleIndex: Long, @SerialName("role_index") val roleIndex: Long,
@SerialName("seq") val seq: Int, @SerialName("seq") val seq: Int,
@SerialName("finish") val finish: Boolean @SerialName("finish") val finish: Boolean
) ): Protobuf<GetGuildMemberListNextToken>
@Serializable @Serializable
data class GuildMemberInfo( data class GuildMemberInfo(

View File

@ -6,11 +6,12 @@ import com.tencent.mobileqq.transfile.FileMsg
import com.tencent.mobileqq.transfile.api.IProtoReqManager import com.tencent.mobileqq.transfile.api.IProtoReqManager
import com.tencent.mobileqq.transfile.protohandler.RichProto import com.tencent.mobileqq.transfile.protohandler.RichProto
import com.tencent.mobileqq.transfile.protohandler.RichProtoProc import com.tencent.mobileqq.transfile.protohandler.RichProtoProc
import io.ktor.util.Identity.decode
import kotlinx.coroutines.suspendCancellableCoroutine import kotlinx.coroutines.suspendCancellableCoroutine
import kotlinx.serialization.ExperimentalSerializationApi import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.decodeFromByteArray import kotlinx.serialization.decodeFromByteArray
import kotlinx.serialization.encodeToByteArray import kotlinx.serialization.encodeToByteArray
import kotlinx.serialization.protobuf.ProtoBuf
import moe.fuqiuluo.qqinterface.servlet.BaseSvc import moe.fuqiuluo.qqinterface.servlet.BaseSvc
import moe.fuqiuluo.shamrock.helper.Level import moe.fuqiuluo.shamrock.helper.Level
import moe.fuqiuluo.shamrock.helper.LogCenter import moe.fuqiuluo.shamrock.helper.LogCenter
@ -19,7 +20,9 @@ import moe.fuqiuluo.shamrock.tools.slice
import moe.fuqiuluo.shamrock.tools.toHexString import moe.fuqiuluo.shamrock.tools.toHexString
import moe.fuqiuluo.shamrock.utils.PlatformUtils import moe.fuqiuluo.shamrock.utils.PlatformUtils
import moe.fuqiuluo.shamrock.xposed.helper.AppRuntimeFetcher import moe.fuqiuluo.shamrock.xposed.helper.AppRuntimeFetcher
import moe.fuqiuluo.symbols.decodeProtobuf
import mqq.app.MobileQQ import mqq.app.MobileQQ
import protobuf.auto.toByteArray
import protobuf.oidb.cmd0xfc2.Oidb0xfc2ChannelInfo import protobuf.oidb.cmd0xfc2.Oidb0xfc2ChannelInfo
import protobuf.oidb.cmd0xfc2.Oidb0xfc2MsgApplyDownloadReq import protobuf.oidb.cmd0xfc2.Oidb0xfc2MsgApplyDownloadReq
import protobuf.oidb.cmd0xfc2.Oidb0xfc2ReqBody import protobuf.oidb.cmd0xfc2.Oidb0xfc2ReqBody
@ -49,8 +52,7 @@ internal object RichProtoSvc: BaseSvc() {
}*/ }*/
suspend fun getGuildFileDownUrl(peerId: String, channelId: String, fileId: String, bizId: Int): String { suspend fun getGuildFileDownUrl(peerId: String, channelId: String, fileId: String, bizId: Int): String {
val buffer = sendOidbAW("OidbSvcTrpcTcp.0xfc2_0", 4034, 0, ProtoBuf.encodeToByteArray( val buffer = sendOidbAW("OidbSvcTrpcTcp.0xfc2_0", 4034, 0, Oidb0xfc2ReqBody(
Oidb0xfc2ReqBody(
msgCmd = 1200, msgCmd = 1200,
msgBusType = 4202, msgBusType = 4202,
msgChannelInfo = Oidb0xfc2ChannelInfo( msgChannelInfo = Oidb0xfc2ChannelInfo(
@ -62,14 +64,16 @@ internal object RichProtoSvc: BaseSvc() {
fieldId = fileId, fieldId = fileId,
supportEncrypt = 0 supportEncrypt = 0
) )
) ).toByteArray()) ?: return ""
)) ?: return ""
val body = oidb_sso.OIDBSSOPkg() val body = oidb_sso.OIDBSSOPkg()
body.mergeFrom(buffer.slice(4)) body.mergeFrom(buffer.slice(4))
ProtoBuf.decodeFromByteArray<Oidb0xfc2RspBody>(body.bytes_bodybuffer.get().toByteArray()).msgApplyDownloadRsp?.let { body.bytes_bodybuffer
it.msgDownloadInfo?.let { .get().toByteArray()
return "https://${it.downloadDomain}${it.downloadUrl}&fname=$fileId&isthumb=0" .decodeProtobuf<Oidb0xfc2RspBody>()
} .msgApplyDownloadRsp?.let {
it.msgDownloadInfo?.let {
return "https://${it.downloadDomain}${it.downloadUrl}&fname=$fileId&isthumb=0"
}
} }
return "" return ""
} }

View File

@ -7,7 +7,7 @@ import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import kotlinx.serialization.decodeFromByteArray import kotlinx.serialization.decodeFromByteArray
import kotlinx.serialization.json.JsonElement import kotlinx.serialization.json.JsonElement
import kotlinx.serialization.protobuf.ProtoBuf
import moe.fuqiuluo.qqinterface.servlet.QFavSvc import moe.fuqiuluo.qqinterface.servlet.QFavSvc
import moe.fuqiuluo.shamrock.remote.action.ActionSession import moe.fuqiuluo.shamrock.remote.action.ActionSession
import moe.fuqiuluo.shamrock.remote.action.IActionHandler import moe.fuqiuluo.shamrock.remote.action.IActionHandler
@ -16,6 +16,7 @@ import moe.fuqiuluo.shamrock.utils.CryptTools
import moe.fuqiuluo.shamrock.utils.DeflateTools import moe.fuqiuluo.shamrock.utils.DeflateTools
import moe.fuqiuluo.shamrock.utils.FileUtils import moe.fuqiuluo.shamrock.utils.FileUtils
import moe.fuqiuluo.symbols.OneBotHandler import moe.fuqiuluo.symbols.OneBotHandler
import moe.fuqiuluo.symbols.decodeProtobuf
import protobuf.fav.WeiyunComm import protobuf.fav.WeiyunComm
@OneBotHandler("fav.add_image_msg") @OneBotHandler("fav.add_image_msg")
@ -74,7 +75,7 @@ internal object FavAddImageMsg: IActionHandler() {
readPacket.readFully(it, 0, it.size) readPacket.readFully(it, 0, it.size)
} }
val resp = ProtoBuf.decodeFromByteArray<WeiyunComm>(data) val resp = data.decodeProtobuf<WeiyunComm>()
.resp!!.fastUploadResourceResp!!.picResultList!!.first() .resp!!.fastUploadResourceResp!!.picResultList!!.first()
val picInfo = resp.picInfo!! val picInfo = resp.picInfo!!
picUrl = picInfo.uri picUrl = picInfo.uri
@ -133,7 +134,7 @@ internal object FavAddImageMsg: IActionHandler() {
val data = ByteArray(dataLength).also { val data = ByteArray(dataLength).also {
readPacket.readFully(it, 0, it.size) readPacket.readFully(it, 0, it.size)
} }
val resp = ProtoBuf.decodeFromByteArray<WeiyunComm>(data).resp!! val resp = data.decodeProtobuf<WeiyunComm>().resp!!
itemId = resp.addRichMediaResp!!.cid itemId = resp.addRichMediaResp!!.cid
} }

View File

@ -6,13 +6,14 @@ import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import kotlinx.serialization.decodeFromByteArray import kotlinx.serialization.decodeFromByteArray
import kotlinx.serialization.json.JsonElement import kotlinx.serialization.json.JsonElement
import kotlinx.serialization.protobuf.ProtoBuf
import moe.fuqiuluo.qqinterface.servlet.QFavSvc import moe.fuqiuluo.qqinterface.servlet.QFavSvc
import moe.fuqiuluo.shamrock.remote.action.ActionSession import moe.fuqiuluo.shamrock.remote.action.ActionSession
import moe.fuqiuluo.shamrock.remote.action.IActionHandler import moe.fuqiuluo.shamrock.remote.action.IActionHandler
import moe.fuqiuluo.shamrock.tools.EmptyJsonString import moe.fuqiuluo.shamrock.tools.EmptyJsonString
import moe.fuqiuluo.shamrock.utils.DeflateTools import moe.fuqiuluo.shamrock.utils.DeflateTools
import moe.fuqiuluo.symbols.OneBotHandler import moe.fuqiuluo.symbols.OneBotHandler
import moe.fuqiuluo.symbols.decodeProtobuf
import protobuf.fav.WeiyunComm import protobuf.fav.WeiyunComm
@OneBotHandler("fav.add_text_msg") @OneBotHandler("fav.add_text_msg")
@ -55,7 +56,7 @@ internal object FavAddTextMsg: IActionHandler() {
val data = ByteArray(dataLength).also { val data = ByteArray(dataLength).also {
readPacket.readFully(it, 0, it.size) readPacket.readFully(it, 0, it.size)
} }
val resp = ProtoBuf.decodeFromByteArray<WeiyunComm>(data).resp!!.addRichMediaResp!! val resp = data.decodeProtobuf<WeiyunComm>().resp!!.addRichMediaResp!!
ok(data = QFavItem(resp.cid), echo) ok(data = QFavItem(resp.cid), echo)
} else { } else {
logic(it.mErrDesc, echo) logic(it.mErrDesc, echo)

View File

@ -9,13 +9,14 @@ import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import kotlinx.serialization.decodeFromByteArray import kotlinx.serialization.decodeFromByteArray
import kotlinx.serialization.json.JsonElement import kotlinx.serialization.json.JsonElement
import kotlinx.serialization.protobuf.ProtoBuf
import moe.fuqiuluo.qqinterface.servlet.QFavSvc import moe.fuqiuluo.qqinterface.servlet.QFavSvc
import moe.fuqiuluo.shamrock.remote.action.ActionSession import moe.fuqiuluo.shamrock.remote.action.ActionSession
import moe.fuqiuluo.shamrock.remote.action.IActionHandler import moe.fuqiuluo.shamrock.remote.action.IActionHandler
import moe.fuqiuluo.shamrock.tools.EmptyJsonString import moe.fuqiuluo.shamrock.tools.EmptyJsonString
import moe.fuqiuluo.shamrock.utils.DeflateTools import moe.fuqiuluo.shamrock.utils.DeflateTools
import moe.fuqiuluo.symbols.OneBotHandler import moe.fuqiuluo.symbols.OneBotHandler
import moe.fuqiuluo.symbols.decodeProtobuf
import protobuf.fav.WeiyunComm import protobuf.fav.WeiyunComm
@OneBotHandler("fav.get_item_content") @OneBotHandler("fav.get_item_content")
@ -47,7 +48,7 @@ internal object FavGetItemContent: IActionHandler() {
readPacket.readFully(it, 0, it.size) readPacket.readFully(it, 0, it.size)
} }
val resp = ProtoBuf.decodeFromByteArray<WeiyunComm>(data).resp!! val resp = data.decodeProtobuf<WeiyunComm>().resp!!
return ok(ItemContent( return ok(ItemContent(
resp.getFavContentResp!!.content!!.joinToString("") { resp.getFavContentResp!!.content!!.joinToString("") {
String(it.richMedia!!.rawData!!) String(it.richMedia!!.rawData!!)

View File

@ -6,13 +6,14 @@ import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import kotlinx.serialization.decodeFromByteArray import kotlinx.serialization.decodeFromByteArray
import kotlinx.serialization.json.JsonElement import kotlinx.serialization.json.JsonElement
import kotlinx.serialization.protobuf.ProtoBuf
import moe.fuqiuluo.qqinterface.servlet.QFavSvc import moe.fuqiuluo.qqinterface.servlet.QFavSvc
import moe.fuqiuluo.shamrock.remote.action.ActionSession import moe.fuqiuluo.shamrock.remote.action.ActionSession
import moe.fuqiuluo.shamrock.remote.action.IActionHandler import moe.fuqiuluo.shamrock.remote.action.IActionHandler
import moe.fuqiuluo.shamrock.tools.EmptyJsonString import moe.fuqiuluo.shamrock.tools.EmptyJsonString
import moe.fuqiuluo.shamrock.utils.DeflateTools import moe.fuqiuluo.shamrock.utils.DeflateTools
import moe.fuqiuluo.symbols.OneBotHandler import moe.fuqiuluo.symbols.OneBotHandler
import moe.fuqiuluo.symbols.decodeProtobuf
import protobuf.fav.WeiyunComm import protobuf.fav.WeiyunComm
@OneBotHandler("fav.get_item_list") @OneBotHandler("fav.get_item_list")
@ -55,7 +56,7 @@ internal object FavGetItemList: IActionHandler() {
val data = ByteArray(dataLength).also { val data = ByteArray(dataLength).also {
readPacket.readFully(it, 0, it.size) readPacket.readFully(it, 0, it.size)
} }
val resp = ProtoBuf.decodeFromByteArray<WeiyunComm>(data).resp!!.getFavListResp!! val resp = data.decodeProtobuf<WeiyunComm>().resp!!.getFavListResp!!
val itemList = arrayListOf<Item>() val itemList = arrayListOf<Item>()
val rawItemList = resp.collections!! val rawItemList = resp.collections!!

View File

@ -8,7 +8,7 @@ import kotlinx.serialization.Serializable
import kotlinx.serialization.decodeFromByteArray import kotlinx.serialization.decodeFromByteArray
import kotlinx.serialization.encodeToByteArray import kotlinx.serialization.encodeToByteArray
import kotlinx.serialization.json.JsonElement import kotlinx.serialization.json.JsonElement
import kotlinx.serialization.protobuf.ProtoBuf
import moe.fuqiuluo.qqinterface.servlet.GProSvc import moe.fuqiuluo.qqinterface.servlet.GProSvc
import moe.fuqiuluo.qqinterface.servlet.structures.GetGuildMemberListNextToken import moe.fuqiuluo.qqinterface.servlet.structures.GetGuildMemberListNextToken
import moe.fuqiuluo.qqinterface.servlet.structures.GuildMemberInfo import moe.fuqiuluo.qqinterface.servlet.structures.GuildMemberInfo
@ -19,6 +19,8 @@ import moe.fuqiuluo.shamrock.tools.EmptyJsonString
import moe.fuqiuluo.shamrock.tools.hex2ByteArray import moe.fuqiuluo.shamrock.tools.hex2ByteArray
import moe.fuqiuluo.shamrock.tools.toHexString import moe.fuqiuluo.shamrock.tools.toHexString
import moe.fuqiuluo.symbols.OneBotHandler import moe.fuqiuluo.symbols.OneBotHandler
import moe.fuqiuluo.symbols.decodeProtobuf
import protobuf.auto.toByteArray
@OneBotHandler("get_guild_member_list") @OneBotHandler("get_guild_member_list")
internal object GetGuildMemberList: IActionHandler() { internal object GetGuildMemberList: IActionHandler() {
@ -29,7 +31,7 @@ internal object GetGuildMemberList: IActionHandler() {
} }
suspend operator fun invoke(guildId: ULong, all: Boolean, nextTokenStr: String, echo: JsonElement = EmptyJsonString): String { suspend operator fun invoke(guildId: ULong, all: Boolean, nextTokenStr: String, echo: JsonElement = EmptyJsonString): String {
val curNextToken = if (nextTokenStr.isEmpty()) null else ProtoBuf.decodeFromByteArray<GetGuildMemberListNextToken>(nextTokenStr.hex2ByteArray()) val curNextToken = if (nextTokenStr.isEmpty()) null else nextTokenStr.hex2ByteArray().decodeProtobuf<GetGuildMemberListNextToken>()
val result = GProSvc.getGuildMemberList( val result = GProSvc.getGuildMemberList(
guildId = guildId, guildId = guildId,
fetchAll = all, fetchAll = all,
@ -62,7 +64,7 @@ internal object GetGuildMemberList: IActionHandler() {
return ok(GetGuildMemberListResult( return ok(GetGuildMemberListResult(
members = members, members = members,
finish = nextToken.finish, finish = nextToken.finish,
nextToken = ProtoBuf.encodeToByteArray(nextToken).toHexString(), nextToken = nextToken.toByteArray().toHexString(),
), echo) ), echo)
} }

View File

@ -2,11 +2,12 @@ package moe.fuqiuluo.shamrock.remote.action.handlers
import kotlinx.atomicfu.atomic import kotlinx.atomicfu.atomic
import kotlinx.serialization.encodeToByteArray import kotlinx.serialization.encodeToByteArray
import kotlinx.serialization.protobuf.ProtoBuf
import moe.fuqiuluo.qqinterface.servlet.BaseSvc import moe.fuqiuluo.qqinterface.servlet.BaseSvc
import moe.fuqiuluo.shamrock.remote.action.ActionSession import moe.fuqiuluo.shamrock.remote.action.ActionSession
import moe.fuqiuluo.shamrock.remote.action.IActionHandler import moe.fuqiuluo.shamrock.remote.action.IActionHandler
import moe.fuqiuluo.symbols.OneBotHandler import moe.fuqiuluo.symbols.OneBotHandler
import protobuf.auto.toByteArray
import protobuf.msg.C2C import protobuf.msg.C2C
import protobuf.msg.ContentHead import protobuf.msg.ContentHead
import protobuf.msg.Elem import protobuf.msg.Elem
@ -47,7 +48,7 @@ internal object SendMsgByResid: IActionHandler() {
msgRand = Random.nextUInt(), msgRand = Random.nextUInt(),
msgVia = 0u msgVia = 0u
) )
BaseSvc.sendBufferAW("MessageSvc.PbSendMsg", true, ProtoBuf.encodeToByteArray(req)) BaseSvc.sendBufferAW("MessageSvc.PbSendMsg", true, req.toByteArray())
return ok("ok", session.echo) return ok("ok", session.echo)
} }
} }

View File

@ -13,7 +13,7 @@ import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.decodeFromByteArray import kotlinx.serialization.decodeFromByteArray
import kotlinx.serialization.json.Json import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonElement import kotlinx.serialization.json.JsonElement
import kotlinx.serialization.protobuf.ProtoBuf
import moe.fuqiuluo.qqinterface.servlet.FriendSvc.requestFriendSystemMsgNew import moe.fuqiuluo.qqinterface.servlet.FriendSvc.requestFriendSystemMsgNew
import moe.fuqiuluo.qqinterface.servlet.GroupSvc import moe.fuqiuluo.qqinterface.servlet.GroupSvc
import moe.fuqiuluo.qqinterface.servlet.GroupSvc.requestGroupSystemMsgNew import moe.fuqiuluo.qqinterface.servlet.GroupSvc.requestGroupSystemMsgNew
@ -31,6 +31,8 @@ import moe.fuqiuluo.shamrock.tools.asJsonObject
import moe.fuqiuluo.shamrock.tools.asString import moe.fuqiuluo.shamrock.tools.asString
import moe.fuqiuluo.shamrock.tools.readBuf32Long import moe.fuqiuluo.shamrock.tools.readBuf32Long
import moe.fuqiuluo.shamrock.xposed.helper.PacketHandler import moe.fuqiuluo.shamrock.xposed.helper.PacketHandler
import moe.fuqiuluo.symbols.decode
import moe.fuqiuluo.symbols.decodeProtobuf
import protobuf.message.MessageContent import protobuf.message.MessageContent
import protobuf.message.MessageHead import protobuf.message.MessageHead
import protobuf.message.MessageBody import protobuf.message.MessageBody
@ -56,7 +58,7 @@ internal object PrimitiveListener {
PacketHandler.register("trpc.msg.olpush.OlPushService.MsgPush") { _, buffer -> PacketHandler.register("trpc.msg.olpush.OlPushService.MsgPush") { _, buffer ->
GlobalScope.launch { GlobalScope.launch {
try { try {
val push = ProtoBuf.decodeFromByteArray<MessagePush>(buffer.slice(4)) val push = buffer.slice(4).decodeProtobuf<MessagePush>()
onMsgPush(push) onMsgPush(push)
} catch (e: Exception) { } catch (e: Exception) {
LogCenter.log(e.stackTraceToString(), Level.WARN) LogCenter.log(e.stackTraceToString(), Level.WARN)
@ -113,7 +115,7 @@ internal object PrimitiveListener {
body.rich?.elements?.filter { body.rich?.elements?.filter {
it.comm != null && it.comm!!.type == 48 it.comm != null && it.comm!!.type == 48
}?.map { }?.map {
ProtoBuf.decodeFromByteArray<RichMediaForPicData>(it.comm!!.data!!) it.comm!!.data!!.decodeProtobuf<RichMediaForPicData>()
}?.forEach { }?.forEach {
it.display?.show?.download?.url?.let { it.display?.show?.download?.url?.let {
RKEY_PATTERN.matcher(it).takeIf { RKEY_PATTERN.matcher(it).takeIf {
@ -129,7 +131,7 @@ internal object PrimitiveListener {
} }
private suspend fun onC2CPoke(msgTime: Long, richMsg: MessageBody) { private suspend fun onC2CPoke(msgTime: Long, richMsg: MessageBody) {
val event = ProtoBuf.decodeFromByteArray<C2CCommonTipsEvent>(richMsg.rawBuffer!!) val event = richMsg.rawBuffer!!.decodeProtobuf<C2CCommonTipsEvent>()
if (event.params == null) return if (event.params == null) return
val params = event.params!!.associate { val params = event.params!!.associate {
@ -156,7 +158,7 @@ internal object PrimitiveListener {
clientInfo: MessagePushClientInfo, clientInfo: MessagePushClientInfo,
richMsg: MessageBody richMsg: MessageBody
) { ) {
val event = ProtoBuf.decodeFromByteArray<FriendApplyEvent>(richMsg.rawBuffer!!) val event = richMsg.rawBuffer!!.decodeProtobuf<FriendApplyEvent>()
if (event.head == null) return if (event.head == null) return
val head = event.head!! val head = event.head!!
val applierUid = head.applierUid val applierUid = head.applierUid
@ -233,15 +235,15 @@ internal object PrimitiveListener {
private suspend fun onGroupUniqueTitleChange(msgTime: Long, richMsg: MessageBody) { private suspend fun onGroupUniqueTitleChange(msgTime: Long, richMsg: MessageBody) {
val event = runCatching { val event = runCatching {
ProtoBuf.decodeFromByteArray<GroupCommonTipsEvent>(richMsg.rawBuffer!!) richMsg.rawBuffer!!.decodeProtobuf<GroupCommonTipsEvent>()
}.getOrElse { }.getOrElse {
val readPacket = ByteReadPacket(richMsg.rawBuffer!!) val readPacket = ByteReadPacket(richMsg.rawBuffer!!)
readPacket.readBuf32Long() readPacket.readBuf32Long()
readPacket.discardExact(1) readPacket.discardExact(1)
ProtoBuf.decodeFromByteArray<GroupCommonTipsEvent>(readPacket.readBytes(readPacket.readShort().toInt()).also { readPacket.readBytes(readPacket.readShort().toInt()).also {
readPacket.release() readPacket.release()
}) }.decodeProtobuf<GroupCommonTipsEvent>()
} }
val groupId = event.groupCode.toLong() val groupId = event.groupCode.toLong()
val detail = event.uniqueTitleChangeDetail!!.first() val detail = event.uniqueTitleChangeDetail!!.first()
@ -279,15 +281,15 @@ internal object PrimitiveListener {
) { ) {
if (clientInfo == null) return if (clientInfo == null) return
val event = runCatching { val event = runCatching {
ProtoBuf.decodeFromByteArray<GroupCommonTipsEvent>(richMsg.rawBuffer!!) richMsg.rawBuffer!!.decodeProtobuf<GroupCommonTipsEvent>()
}.getOrElse { }.getOrElse {
val readPacket = ByteReadPacket(richMsg.rawBuffer!!) val readPacket = ByteReadPacket(richMsg.rawBuffer!!)
readPacket.readBuf32Long() readPacket.readBuf32Long()
readPacket.discardExact(1) readPacket.discardExact(1)
ProtoBuf.decodeFromByteArray<GroupCommonTipsEvent>(readPacket.readBytes(readPacket.readShort().toInt()).also { readPacket.readBytes(readPacket.readShort().toInt()).also {
readPacket.release() readPacket.release()
}) }.decodeProtobuf<GroupCommonTipsEvent>()
} }
val groupId = event.groupCode.toLong() val groupId = event.groupCode.toLong()
val detail = event.essenceMsgInfo!!.first() val detail = event.essenceMsgInfo!!.first()
@ -326,15 +328,15 @@ internal object PrimitiveListener {
private suspend fun onGroupPokeAndGroupSign(time: Long, richMsg: MessageBody) { private suspend fun onGroupPokeAndGroupSign(time: Long, richMsg: MessageBody) {
val event = runCatching { val event = runCatching {
ProtoBuf.decodeFromByteArray<GroupCommonTipsEvent>(richMsg.rawBuffer!!) richMsg.rawBuffer!!.decodeProtobuf<GroupCommonTipsEvent>()
}.getOrElse { }.getOrElse {
val readPacket = ByteReadPacket(richMsg.rawBuffer!!) val readPacket = ByteReadPacket(richMsg.rawBuffer!!)
readPacket.discardExact(4) readPacket.discardExact(4)
readPacket.discardExact(1) readPacket.discardExact(1)
ProtoBuf.decodeFromByteArray<GroupCommonTipsEvent>(readPacket.readBytes(readPacket.readShort().toInt()).also { readPacket.readBytes(readPacket.readShort().toInt()).also {
readPacket.release() readPacket.release()
}) }.decodeProtobuf<GroupCommonTipsEvent>()
} }
val groupId = event.groupCode.toLong() val groupId = event.groupCode.toLong()
val detail = event.baseTips!!.first() val detail = event.baseTips!!.first()
@ -379,7 +381,7 @@ internal object PrimitiveListener {
} }
private suspend fun onC2CRecall(time: Long, richMsg: MessageBody) { private suspend fun onC2CRecall(time: Long, richMsg: MessageBody) {
val event = ProtoBuf.decodeFromByteArray<C2CRecallEvent>(richMsg.rawBuffer!!) val event = richMsg.rawBuffer!!.decodeProtobuf<C2CRecallEvent>()
val head = event.head!! val head = event.head!!
val operationUid = head.operator!! val operationUid = head.operator!!
@ -404,7 +406,7 @@ internal object PrimitiveListener {
} }
private suspend fun onGroupMemIncreased(time: Long, richMsg: MessageBody) { private suspend fun onGroupMemIncreased(time: Long, richMsg: MessageBody) {
val event = ProtoBuf.decodeFromByteArray<GroupListChangeEvent>(richMsg.rawBuffer!!) val event = richMsg.rawBuffer!!.decodeProtobuf<GroupListChangeEvent>()
val groupCode = event.groupCode val groupCode = event.groupCode
val targetUid = event.memberUid val targetUid = event.memberUid
val type = event.type val type = event.type
@ -434,7 +436,7 @@ internal object PrimitiveListener {
} }
private suspend fun onGroupMemberDecreased(time: Long, richMsg: MessageBody) { private suspend fun onGroupMemberDecreased(time: Long, richMsg: MessageBody) {
val event = ProtoBuf.decodeFromByteArray<GroupListChangeEvent>(richMsg.rawBuffer!!) val event = richMsg.rawBuffer!!.decodeProtobuf<GroupListChangeEvent>()
val groupCode = event.groupCode val groupCode = event.groupCode
val targetUid = event.memberUid val targetUid = event.memberUid
val type = event.type val type = event.type
@ -467,7 +469,7 @@ internal object PrimitiveListener {
} }
private suspend fun onGroupAdminChange(msgTime: Long, richMsg: MessageBody) { private suspend fun onGroupAdminChange(msgTime: Long, richMsg: MessageBody) {
val event = ProtoBuf.decodeFromByteArray<GroupAdminChangeEvent>(richMsg.rawBuffer!!) val event = richMsg.rawBuffer!!.decodeProtobuf<GroupAdminChangeEvent>()
val groupCode = event.groupCode val groupCode = event.groupCode
if (event.operation == null) return if (event.operation == null) return
val operation = event.operation!! val operation = event.operation!!
@ -494,7 +496,7 @@ internal object PrimitiveListener {
} }
private suspend fun onGroupBan(msgTime: Long, richMsg: MessageBody) { private suspend fun onGroupBan(msgTime: Long, richMsg: MessageBody) {
val event = ProtoBuf.decodeFromByteArray<GroupBanEvent>(richMsg.rawBuffer!!) val event = richMsg.rawBuffer!!.decodeProtobuf<GroupBanEvent>()
val groupCode = event.groupCode.toLong() val groupCode = event.groupCode.toLong()
val operatorUid = event.operatorUid val operatorUid = event.operatorUid
val wholeBan = event.target?.target?.targetUid == null val wholeBan = event.target?.target?.targetUid == null
@ -520,14 +522,14 @@ internal object PrimitiveListener {
private suspend fun onGroupRecall(time: Long, richMsg: MessageBody) { private suspend fun onGroupRecall(time: Long, richMsg: MessageBody) {
val event = runCatching { val event = runCatching {
ProtoBuf.decodeFromByteArray<GroupCommonTipsEvent>(richMsg.rawBuffer!!) richMsg.rawBuffer!!.decodeProtobuf<GroupCommonTipsEvent>()
}.getOrElse { }.getOrElse {
val readPacket = ByteReadPacket(richMsg.rawBuffer!!) val readPacket = ByteReadPacket(richMsg.rawBuffer!!)
readPacket.discardExact(4) readPacket.discardExact(4)
readPacket.discardExact(1) readPacket.discardExact(1)
ProtoBuf.decodeFromByteArray<GroupCommonTipsEvent>(readPacket.readBytes(readPacket.readShort().toInt()).also { readPacket.readBytes(readPacket.readShort().toInt()).also {
readPacket.release() readPacket.release()
}) }.decodeProtobuf<GroupCommonTipsEvent>()
} }
val groupCode = event.groupCode.toLong() val groupCode = event.groupCode.toLong()
val detail = event.recallDetails!! val detail = event.recallDetails!!
@ -555,7 +557,7 @@ internal object PrimitiveListener {
private suspend fun onGroupApply(time: Long, contentHead: MessageContent, richMsg: MessageBody) { private suspend fun onGroupApply(time: Long, contentHead: MessageContent, richMsg: MessageBody) {
when (contentHead.msgType) { when (contentHead.msgType) {
84 -> { 84 -> {
val event = ProtoBuf.decodeFromByteArray<GroupApplyEvent>(richMsg.rawBuffer!!) val event = richMsg.rawBuffer!!.decodeProtobuf<GroupApplyEvent>()
val groupCode = event.groupCode val groupCode = event.groupCode
val applierUid = event.applierUid val applierUid = event.applierUid
val reason = event.applyMsg ?: "" val reason = event.applyMsg ?: ""
@ -587,7 +589,7 @@ internal object PrimitiveListener {
} }
} }
528 -> { 528 -> {
val event = ProtoBuf.decodeFromByteArray<GroupInvitedApplyEvent>(richMsg.rawBuffer!!) val event = richMsg.rawBuffer!!.decodeProtobuf<GroupInvitedApplyEvent>()
val groupCode = event.applyInfo?.groupCode ?: return val groupCode = event.applyInfo?.groupCode ?: return
val applierUid = event.applyInfo?.applierUid ?: return val applierUid = event.applyInfo?.applierUid ?: return
var applier = ContactHelper.getUinByUidAsync(applierUid).toLong() var applier = ContactHelper.getUinByUidAsync(applierUid).toLong()
@ -624,7 +626,7 @@ internal object PrimitiveListener {
} }
private suspend fun onInviteGroup(time: Long, msgHead: MessageHead, richMsg: MessageBody) { private suspend fun onInviteGroup(time: Long, msgHead: MessageHead, richMsg: MessageBody) {
val event = ProtoBuf.decodeFromByteArray<GroupInviteEvent>(richMsg.rawBuffer!!) val event = richMsg.rawBuffer!!.decodeProtobuf<GroupInviteEvent>()
val groupCode = event.groupCode val groupCode = event.groupCode
val invitorUid = event.inviterUid val invitorUid = event.inviterUid
val invitor = ContactHelper.getUinByUidAsync(invitorUid).toLong() val invitor = ContactHelper.getUinByUidAsync(invitorUid).toLong()