mirror of
https://github.com/whitechi73/OpenShamrock.git
synced 2024-08-14 05:12:17 +00:00
Compare commits
6 Commits
5637db43be
...
1afc0ac6a6
Author | SHA1 | Date | |
---|---|---|---|
1afc0ac6a6 | |||
638bf72392 | |||
07364c8298 | |||
ee6e13a5bb | |||
c3934778c7 | |||
13a49dd70b |
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
[submodule "kritor"]
|
||||
path = kritor
|
||||
url = https://github.com/KarinJS/kritor
|
@ -9,6 +9,6 @@ java {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(DEPENDENCY_PROTOBUF)
|
||||
//implementation(DEPENDENCY_PROTOBUF)
|
||||
implementation(kotlinx("serialization-protobuf", "1.6.2"))
|
||||
}
|
7
annotations/src/main/java/kritor/service/Grpc.kt
Normal file
7
annotations/src/main/java/kritor/service/Grpc.kt
Normal file
@ -0,0 +1,7 @@
|
||||
package kritor.service
|
||||
|
||||
@Target(AnnotationTarget.FUNCTION)
|
||||
annotation class Grpc(
|
||||
val serviceName: String,
|
||||
val funcName: String
|
||||
)
|
@ -5,6 +5,8 @@ import kotlinx.serialization.protobuf.ProtoBuf
|
||||
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
val EMPTY_BYTE_ARRAY = ByteArray(0)
|
||||
|
||||
interface Protobuf<T: Protobuf<T>>
|
||||
|
||||
inline fun <reified T: Protobuf<T>> ByteArray.decodeProtobuf(to: KClass<T>? = null): T {
|
||||
|
@ -18,12 +18,17 @@ internal object InitHandler: ModuleHandler() {
|
||||
|
||||
val maps = hashMapOf<String, Any?>()
|
||||
|
||||
RPCPort.update(context, maps)
|
||||
RPCAddress.update(context, maps)
|
||||
ForceTablet.update(context, maps)
|
||||
ActiveRPC.update(context, maps)
|
||||
AliveReply.update(context, maps)
|
||||
AntiJvmTrace.update(context, maps)
|
||||
DebugMode.update(context, maps)
|
||||
EnableOldBDH.update(context, maps)
|
||||
EnableSelfMessage.update(context, maps)
|
||||
ForceTablet.update(context, maps)
|
||||
PassiveRPC.update(context, maps)
|
||||
ResourceGroup.update(context, maps)
|
||||
RPCAddress.update(context, maps)
|
||||
RPCPort.update(context, maps)
|
||||
|
||||
callback(context, 1, maps)
|
||||
}
|
||||
|
@ -7,9 +7,6 @@ val DEPENDENCY_ANDROIDX = arrayOf(
|
||||
"androidx.activity:activity-compose:1.7.2",
|
||||
)
|
||||
|
||||
|
||||
const val DEPENDENCY_PROTOBUF = "com.google.protobuf:protobuf-java:3.24.0"
|
||||
|
||||
fun room(name: String) = "androidx.room:room-$name:${Versions.roomVersion}"
|
||||
|
||||
fun kotlinx(name: String, version: String) = "org.jetbrains.kotlinx:kotlinx-$name:$version"
|
||||
|
1
kritor
Submodule
1
kritor
Submodule
Submodule kritor added at f4fa15754e
@ -15,7 +15,7 @@ dependencies {
|
||||
implementation("com.google.devtools.ksp:symbol-processing-api:1.9.21-1.0.15")
|
||||
implementation("com.squareup:kotlinpoet:1.14.2")
|
||||
|
||||
implementation(DEPENDENCY_PROTOBUF)
|
||||
//implementation(DEPENDENCY_PROTOBUF)
|
||||
implementation(kotlinx("serialization-protobuf", "1.6.2"))
|
||||
|
||||
ksp("dev.zacsweers.autoservice:auto-service-ksp:1.1.0")
|
||||
|
@ -37,7 +37,7 @@ android {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(DEPENDENCY_PROTOBUF)
|
||||
//implementation(DEPENDENCY_PROTOBUF)
|
||||
implementation(kotlinx("serialization-protobuf", "1.6.2"))
|
||||
implementation(kotlinx("serialization-json", "1.6.2"))
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
@file:OptIn(ExperimentalSerializationApi::class)
|
||||
package protobuf.oidb.cmd0x11c5
|
||||
|
||||
import com.google.protobuf.Internal.EMPTY_BYTE_ARRAY
|
||||
import moe.fuqiuluo.symbols.EMPTY_BYTE_ARRAY
|
||||
import kotlinx.serialization.ExperimentalSerializationApi
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.protobuf.ProtoNumber
|
||||
|
@ -1,6 +1,6 @@
|
||||
package protobuf.oidb.cmd0x388
|
||||
|
||||
import com.google.protobuf.Internal.EMPTY_BYTE_ARRAY
|
||||
import moe.fuqiuluo.symbols.EMPTY_BYTE_ARRAY
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.protobuf.ProtoNumber
|
||||
import moe.fuqiuluo.symbols.Protobuf
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
package protobuf.oidb.cmd0x388
|
||||
|
||||
import com.google.protobuf.Internal.EMPTY_BYTE_ARRAY
|
||||
import moe.fuqiuluo.symbols.EMPTY_BYTE_ARRAY
|
||||
import kotlinx.serialization.ExperimentalSerializationApi
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.protobuf.ProtoNumber
|
||||
|
@ -39,3 +39,6 @@ include(
|
||||
include(":protobuf")
|
||||
include(":processor")
|
||||
include(":annotations")
|
||||
include(":kritor")
|
||||
|
||||
project(":kritor").projectDir = file("kritor/protos")
|
@ -5,6 +5,7 @@ plugins {
|
||||
id("org.jetbrains.kotlin.android")
|
||||
id("kotlin-kapt")
|
||||
id("com.google.devtools.ksp") version "1.9.22-1.0.17"
|
||||
id("com.google.protobuf") version "0.9.4"
|
||||
kotlin("plugin.serialization") version "1.9.22"
|
||||
}
|
||||
|
||||
@ -63,6 +64,8 @@ dependencies {
|
||||
compileOnly ("de.robv.android.xposed:api:82")
|
||||
compileOnly (project(":qqinterface"))
|
||||
|
||||
protobuf(project(":kritor"))
|
||||
|
||||
implementation(project(":protobuf"))
|
||||
implementation(project(":annotations"))
|
||||
ksp(project(":processor"))
|
||||
@ -72,7 +75,7 @@ dependencies {
|
||||
DEPENDENCY_ANDROIDX.forEach {
|
||||
implementation(it)
|
||||
}
|
||||
implementation(DEPENDENCY_PROTOBUF)
|
||||
//implementation(DEPENDENCY_PROTOBUF)
|
||||
|
||||
implementation(room("runtime"))
|
||||
kapt(room("compiler"))
|
||||
@ -84,7 +87,12 @@ dependencies {
|
||||
implementation(ktor("client", "core"))
|
||||
implementation(ktor("client", "okhttp"))
|
||||
implementation(ktor("serialization", "kotlinx-json"))
|
||||
implementation(ktor("network", "tls-certificates"))
|
||||
|
||||
implementation("io.grpc:grpc-stub:1.62.2")
|
||||
implementation("io.grpc:grpc-protobuf-lite:1.62.2")
|
||||
implementation("com.google.protobuf:protobuf-kotlin-lite:3.25.3")
|
||||
implementation("io.grpc:grpc-kotlin-stub:1.4.1")
|
||||
implementation("io.grpc:grpc-okhttp:1.62.2")
|
||||
|
||||
testImplementation("junit:junit:4.13.2")
|
||||
androidTestImplementation("androidx.test.ext:junit:1.1.5")
|
||||
@ -92,3 +100,46 @@ dependencies {
|
||||
androidTestImplementation(platform("androidx.compose:compose-bom:2023.06.01"))
|
||||
androidTestImplementation("androidx.compose.ui:ui-test-junit4")
|
||||
}
|
||||
|
||||
tasks.withType<KotlinCompile>().all {
|
||||
kotlinOptions {
|
||||
freeCompilerArgs = listOf("-opt-in=kotlin.RequiresOptIn")
|
||||
}
|
||||
}
|
||||
|
||||
protobuf {
|
||||
protoc {
|
||||
artifact = "com.google.protobuf:protoc:3.25.3"
|
||||
}
|
||||
plugins {
|
||||
create("java") {
|
||||
artifact = "io.grpc:protoc-gen-grpc-java:1.62.2"
|
||||
}
|
||||
create("grpc") {
|
||||
artifact = "io.grpc:protoc-gen-grpc-java:1.62.2"
|
||||
}
|
||||
create("grpckt") {
|
||||
artifact = "io.grpc:protoc-gen-grpc-kotlin:1.4.1:jdk8@jar"
|
||||
}
|
||||
}
|
||||
generateProtoTasks {
|
||||
all().forEach {
|
||||
it.plugins {
|
||||
create("java") {
|
||||
option("lite")
|
||||
}
|
||||
create("grpc") {
|
||||
option("lite")
|
||||
}
|
||||
create("grpckt") {
|
||||
option("lite")
|
||||
}
|
||||
}
|
||||
it.builtins {
|
||||
create("kotlin") {
|
||||
option("lite")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
43
xposed/src/main/assets/config.properties
Normal file
43
xposed/src/main/assets/config.properties
Normal file
@ -0,0 +1,43 @@
|
||||
# Shamrock Config
|
||||
|
||||
# 资源上传群组
|
||||
resource_group=883536416
|
||||
|
||||
# 强制使用平板模式
|
||||
force_tablet=false
|
||||
|
||||
# 被动(反向)RPC开关
|
||||
passive_rpc=false
|
||||
# 被动(反向)RPC地址
|
||||
rpc_address=
|
||||
# 第一个被动RPC鉴权token
|
||||
rpc_address.ticket=
|
||||
# 如果有多个请使用
|
||||
# 我是第二个地址
|
||||
#rpc_address.1=
|
||||
# 第二个被动RPC鉴权token
|
||||
#rpc_address.1.ticket=
|
||||
|
||||
# 主动(正向)RPC开关
|
||||
active_rpc=false
|
||||
# 主动(正向)RPC端口
|
||||
rpc_port=5700
|
||||
# 主动RPC鉴权token
|
||||
active_ticket=
|
||||
# 多鉴权token支持
|
||||
# 第二个主动RPC鉴权token
|
||||
#active_ticket.1=
|
||||
|
||||
# 自回复开关
|
||||
#alive_reply=false
|
||||
# 自回复消息
|
||||
enable_self_message=false
|
||||
|
||||
# 旧BDH兼容开关
|
||||
enable_old_bdh=false
|
||||
|
||||
# 反JVM调用栈跟踪
|
||||
anti_jvm_trace=true
|
||||
|
||||
# 调试模式
|
||||
#debug=false
|
33
xposed/src/main/java/kritor/server/KritorServer.kt
Normal file
33
xposed/src/main/java/kritor/server/KritorServer.kt
Normal file
@ -0,0 +1,33 @@
|
||||
@file:OptIn(ExperimentalCoroutinesApi::class)
|
||||
package kritor.server
|
||||
|
||||
import io.grpc.Grpc
|
||||
import io.grpc.InsecureServerCredentials
|
||||
import io.grpc.ServerBuilder
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kritor.service.*
|
||||
import moe.fuqiuluo.shamrock.helper.LogCenter
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
|
||||
class KritorServer(
|
||||
private val port: Int
|
||||
): CoroutineScope {
|
||||
private val server = Grpc.newServerBuilderForPort(port, InsecureServerCredentials.create())
|
||||
.addService(Authentication)
|
||||
.build()!!
|
||||
|
||||
fun start(block: Boolean = false) {
|
||||
LogCenter.log("KritorServer started at port $port.")
|
||||
server.start()
|
||||
|
||||
if (block) {
|
||||
server.awaitTermination()
|
||||
}
|
||||
}
|
||||
|
||||
override val coroutineContext: CoroutineContext =
|
||||
Dispatchers.IO.limitedParallelism(12)
|
||||
}
|
49
xposed/src/main/java/kritor/service/Authentication.kt
Normal file
49
xposed/src/main/java/kritor/service/Authentication.kt
Normal file
@ -0,0 +1,49 @@
|
||||
package kritor.service
|
||||
|
||||
import io.kritor.AuthCode
|
||||
import io.kritor.AuthReq
|
||||
import io.kritor.AuthRsp
|
||||
import io.kritor.AuthenticationGrpcKt
|
||||
import io.kritor.authRsp
|
||||
import moe.fuqiuluo.shamrock.config.ActiveTicket
|
||||
import moe.fuqiuluo.shamrock.config.ShamrockConfig
|
||||
import qq.service.QQInterfaces
|
||||
|
||||
object Authentication: AuthenticationGrpcKt.AuthenticationCoroutineImplBase() {
|
||||
@Grpc("Authentication", "Auth")
|
||||
override suspend fun auth(request: AuthReq): AuthRsp {
|
||||
if (QQInterfaces.app.account != request.account) {
|
||||
return authRsp {
|
||||
code = AuthCode.NO_ACCOUNT
|
||||
msg = "No such account"
|
||||
}
|
||||
}
|
||||
|
||||
val activeTicketName = ActiveTicket.name()
|
||||
var index = 0
|
||||
while (true) {
|
||||
val ticket = ShamrockConfig.getProperty(activeTicketName + if (index == 0) "" else ".$index", null)
|
||||
if (ticket.isNullOrEmpty()) {
|
||||
if (index == 0) {
|
||||
return authRsp {
|
||||
code = AuthCode.OK
|
||||
msg = "OK"
|
||||
}
|
||||
} else {
|
||||
break
|
||||
}
|
||||
} else if (ticket == request.ticket) {
|
||||
return authRsp {
|
||||
code = AuthCode.OK
|
||||
msg = "OK"
|
||||
}
|
||||
}
|
||||
index++
|
||||
}
|
||||
|
||||
return authRsp {
|
||||
code = AuthCode.NO_TICKET
|
||||
msg = "Invalid ticket"
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
package moe.fuqiuluo.shamrock.config
|
||||
|
||||
object ActiveTicket: ConfigKey<String>() {
|
||||
override fun name(): String = "active_ticket"
|
||||
|
||||
override fun default(): String = ""
|
||||
}
|
@ -10,3 +10,6 @@ abstract class ConfigKey<T> {
|
||||
}
|
||||
}
|
||||
|
||||
internal inline fun <reified Type, reified T: ConfigKey<Type>> T.get(): Type {
|
||||
return ShamrockConfig[this]
|
||||
}
|
||||
|
@ -1,6 +1,8 @@
|
||||
package moe.fuqiuluo.shamrock.config
|
||||
|
||||
import android.content.Intent
|
||||
import moe.fuqiuluo.shamrock.helper.LogCenter
|
||||
import moe.fuqiuluo.shamrock.xposed.loader.LuoClassloader.moduleLoader
|
||||
import mqq.app.MobileQQ
|
||||
import java.util.Properties
|
||||
|
||||
@ -12,15 +14,28 @@ private val configFile = configDir.resolve("config.prop")
|
||||
|
||||
private val configKeys = setOf(
|
||||
ActiveRPC,
|
||||
AntiJvmTrace,
|
||||
ForceTablet,
|
||||
PassiveRPC,
|
||||
ResourceGroup,
|
||||
RPCAddress,
|
||||
RPCPort
|
||||
RPCPort,
|
||||
)
|
||||
|
||||
internal object ShamrockConfig: Properties() {
|
||||
init {
|
||||
if (!configFile.exists()) {
|
||||
moduleLoader.getResourceAsStream("assets/config.properties")?.use {
|
||||
configDir.resolve("default.prop").outputStream().use { output ->
|
||||
it.copyTo(output)
|
||||
}
|
||||
}
|
||||
moduleLoader.getResourceAsStream("assets/config.properties")?.use {
|
||||
configFile.outputStream().use { output ->
|
||||
it.copyTo(output)
|
||||
}
|
||||
}
|
||||
}
|
||||
if (configFile.exists()) configFile.inputStream().use {
|
||||
load(it)
|
||||
}
|
||||
@ -39,13 +54,34 @@ internal object ShamrockConfig: Properties() {
|
||||
fun updateConfig(intent: Intent? = null) {
|
||||
intent?.let {
|
||||
for (key in configKeys) {
|
||||
when (key.default()) {
|
||||
is String -> {
|
||||
val value = intent.getStringExtra(key.name())
|
||||
if (value != null) setProperty(key.name(), value)
|
||||
}
|
||||
is Boolean -> {
|
||||
val value = intent.getBooleanExtra(key.name(), key.default() as Boolean)
|
||||
setProperty(key.name(), value.toString())
|
||||
}
|
||||
is Int -> {
|
||||
val value = intent.getIntExtra(key.name(), key.default() as Int)
|
||||
setProperty(key.name(), value.toString())
|
||||
}
|
||||
is Long -> {
|
||||
val value = intent.getLongExtra(key.name(), key.default() as Long)
|
||||
setProperty(key.name(), value.toString())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (getProperty(ActiveTicket.name()).isNullOrEmpty()) {
|
||||
setProperty(ActiveTicket.name(), "") // 初始化ticket
|
||||
}
|
||||
|
||||
setProperty(IsInit.name(), "true")
|
||||
}
|
||||
configFile.outputStream().use {
|
||||
store(it, "Shamrock Config ${System.currentTimeMillis()}")
|
||||
store(it, "Shamrock Config")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -10,6 +10,7 @@ import moe.fuqiuluo.shamrock.helper.Level
|
||||
import moe.fuqiuluo.shamrock.helper.LogCenter
|
||||
import moe.fuqiuluo.shamrock.tools.hookMethod
|
||||
import moe.fuqiuluo.shamrock.utils.PlatformUtils
|
||||
import qq.service.internals.AioListener
|
||||
import qq.service.internals.msgService
|
||||
|
||||
internal object NTServiceFetcher {
|
||||
@ -58,7 +59,7 @@ internal object NTServiceFetcher {
|
||||
|
||||
try {
|
||||
LogCenter.log("Register MSG listener successfully.")
|
||||
//msgService.addMsgListener(AioListener)
|
||||
msgService.addMsgListener(AioListener)
|
||||
|
||||
// 接口缺失 暂不使用
|
||||
//groupService.addKernelGroupListener(GroupEventListener)
|
||||
|
@ -4,12 +4,38 @@ package moe.fuqiuluo.shamrock.xposed.actions
|
||||
|
||||
import android.content.Context
|
||||
import kotlinx.coroutines.DelicateCoroutinesApi
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.launch
|
||||
import kritor.server.KritorServer
|
||||
import moe.fuqiuluo.shamrock.config.ActiveRPC
|
||||
import moe.fuqiuluo.shamrock.config.RPCPort
|
||||
import moe.fuqiuluo.shamrock.config.ShamrockConfig
|
||||
import moe.fuqiuluo.shamrock.config.get
|
||||
import moe.fuqiuluo.shamrock.helper.Level
|
||||
import moe.fuqiuluo.shamrock.helper.LogCenter
|
||||
import moe.fuqiuluo.symbols.Process
|
||||
import moe.fuqiuluo.symbols.XposedHook
|
||||
|
||||
private lateinit var server: KritorServer
|
||||
|
||||
@XposedHook(Process.MAIN, priority = 10)
|
||||
internal class InitRemoteService : IAction {
|
||||
override fun invoke(ctx: Context) {
|
||||
GlobalScope.launch {
|
||||
runCatching {
|
||||
if (ActiveRPC.get()) {
|
||||
if (!::server.isInitialized) {
|
||||
server = KritorServer(RPCPort.get())
|
||||
server.start()
|
||||
}
|
||||
} else {
|
||||
LogCenter.log("ActiveRPC is disabled, KritorServer will not be started.")
|
||||
}
|
||||
|
||||
|
||||
}.onFailure {
|
||||
LogCenter.log("Start RPC failed: ${it.message}", Level.ERROR)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -34,8 +34,6 @@ internal object NativeLoader {
|
||||
XposedBridge.log("[Shamrock] 反射检测到 Android x86")
|
||||
true
|
||||
} else false
|
||||
}.onFailure {
|
||||
XposedBridge.log("[Shamrock] ${it.stackTraceToString()}")
|
||||
}.getOrElse { false }
|
||||
|
||||
private fun getLibFilePath(name: String): String {
|
||||
|
314
xposed/src/main/java/qq/service/internals/AioListener.kt
Normal file
314
xposed/src/main/java/qq/service/internals/AioListener.kt
Normal file
@ -0,0 +1,314 @@
|
||||
package qq.service.internals
|
||||
|
||||
import com.tencent.qqnt.kernel.nativeinterface.BroadcastHelperTransNotifyInfo
|
||||
import com.tencent.qqnt.kernel.nativeinterface.Contact
|
||||
import com.tencent.qqnt.kernel.nativeinterface.ContactMsgBoxInfo
|
||||
import com.tencent.qqnt.kernel.nativeinterface.CustomWithdrawConfig
|
||||
import com.tencent.qqnt.kernel.nativeinterface.DevInfo
|
||||
import com.tencent.qqnt.kernel.nativeinterface.DownloadRelateEmojiResultInfo
|
||||
import com.tencent.qqnt.kernel.nativeinterface.EmojiNotifyInfo
|
||||
import com.tencent.qqnt.kernel.nativeinterface.EmojiResourceInfo
|
||||
import com.tencent.qqnt.kernel.nativeinterface.FileTransNotifyInfo
|
||||
import com.tencent.qqnt.kernel.nativeinterface.FirstViewDirectMsgNotifyInfo
|
||||
import com.tencent.qqnt.kernel.nativeinterface.FirstViewGroupGuildInfo
|
||||
import com.tencent.qqnt.kernel.nativeinterface.FreqLimitInfo
|
||||
import com.tencent.qqnt.kernel.nativeinterface.GroupFileListResult
|
||||
import com.tencent.qqnt.kernel.nativeinterface.GroupGuildNotifyInfo
|
||||
import com.tencent.qqnt.kernel.nativeinterface.GroupItem
|
||||
import com.tencent.qqnt.kernel.nativeinterface.GuildInteractiveNotificationItem
|
||||
import com.tencent.qqnt.kernel.nativeinterface.GuildMsgAbFlag
|
||||
import com.tencent.qqnt.kernel.nativeinterface.GuildNotificationAbstractInfo
|
||||
import com.tencent.qqnt.kernel.nativeinterface.HitRelatedEmojiWordsResult
|
||||
import com.tencent.qqnt.kernel.nativeinterface.IKernelMsgListener
|
||||
import com.tencent.qqnt.kernel.nativeinterface.ImportOldDbMsgNotifyInfo
|
||||
import com.tencent.qqnt.kernel.nativeinterface.InputStatusInfo
|
||||
import com.tencent.qqnt.kernel.nativeinterface.KickedInfo
|
||||
import com.tencent.qqnt.kernel.nativeinterface.MsgAbstract
|
||||
import com.tencent.qqnt.kernel.nativeinterface.MsgElement
|
||||
import com.tencent.qqnt.kernel.nativeinterface.MsgRecord
|
||||
import com.tencent.qqnt.kernel.nativeinterface.MsgSetting
|
||||
import com.tencent.qqnt.kernel.nativeinterface.RecvdOrder
|
||||
import com.tencent.qqnt.kernel.nativeinterface.RelatedWordEmojiInfo
|
||||
import com.tencent.qqnt.kernel.nativeinterface.SearchGroupFileResult
|
||||
import com.tencent.qqnt.kernel.nativeinterface.TabStatusInfo
|
||||
import com.tencent.qqnt.kernel.nativeinterface.TempChatInfo
|
||||
import com.tencent.qqnt.kernel.nativeinterface.UnreadCntInfo
|
||||
import moe.fuqiuluo.shamrock.helper.Level
|
||||
import moe.fuqiuluo.shamrock.helper.LogCenter
|
||||
|
||||
object AioListener: IKernelMsgListener {
|
||||
override fun onRecvMsg(arrayList: ArrayList<MsgRecord>?) {
|
||||
|
||||
}
|
||||
|
||||
override fun onMsgRecall(chatType: Int, peerId: String, msgId: Long) {
|
||||
LogCenter.log("onMsgRecall($chatType, $peerId, $msgId)")
|
||||
}
|
||||
|
||||
override fun onAddSendMsg(record: MsgRecord) {
|
||||
|
||||
}
|
||||
|
||||
override fun onMsgInfoListUpdate(msgList: ArrayList<MsgRecord>?) {
|
||||
|
||||
}
|
||||
|
||||
override fun onTempChatInfoUpdate(tempChatInfo: TempChatInfo) {
|
||||
|
||||
}
|
||||
|
||||
override fun onMsgAbstractUpdate(arrayList: ArrayList<MsgAbstract>?) {
|
||||
//arrayList?.forEach {
|
||||
// LogCenter.log("onMsgAbstractUpdate($it)", Level.WARN)
|
||||
//}
|
||||
}
|
||||
|
||||
override fun onRecvMsgSvrRspTransInfo(
|
||||
j2: Long,
|
||||
contact: Contact?,
|
||||
i2: Int,
|
||||
i3: Int,
|
||||
str: String?,
|
||||
bArr: ByteArray?
|
||||
) {
|
||||
LogCenter.log("onRecvMsgSvrRspTransInfo($j2, $contact, $i2, $i3, $str)", Level.DEBUG)
|
||||
}
|
||||
|
||||
override fun onRecvS2CMsg(arrayList: ArrayList<Byte>?) {
|
||||
LogCenter.log("onRecvS2CMsg(${arrayList.toString()})", Level.DEBUG)
|
||||
}
|
||||
|
||||
override fun onRecvSysMsg(arrayList: ArrayList<Byte>?) {
|
||||
LogCenter.log("onRecvSysMsg(${arrayList.toString()})", Level.DEBUG)
|
||||
}
|
||||
|
||||
override fun onBroadcastHelperDownloadComplete(broadcastHelperTransNotifyInfo: BroadcastHelperTransNotifyInfo?) {}
|
||||
|
||||
override fun onBroadcastHelperProgerssUpdate(broadcastHelperTransNotifyInfo: BroadcastHelperTransNotifyInfo?) {}
|
||||
|
||||
override fun onChannelFreqLimitInfoUpdate(
|
||||
contact: Contact?,
|
||||
z: Boolean,
|
||||
freqLimitInfo: FreqLimitInfo?
|
||||
) {
|
||||
|
||||
}
|
||||
|
||||
override fun onContactUnreadCntUpdate(unreadMap: HashMap<Int, HashMap<String, UnreadCntInfo>>) {
|
||||
// 推送未读消息数量
|
||||
}
|
||||
|
||||
override fun onCustomWithdrawConfigUpdate(customWithdrawConfig: CustomWithdrawConfig?) {
|
||||
LogCenter.log("onCustomWithdrawConfigUpdate: " + customWithdrawConfig.toString(), Level.DEBUG)
|
||||
}
|
||||
|
||||
override fun onDraftUpdate(contact: Contact?, arrayList: ArrayList<MsgElement>?, j2: Long) {
|
||||
LogCenter.log("onDraftUpdate: " + contact.toString() + "|" + arrayList + "|" + j2.toString(), Level.DEBUG)
|
||||
}
|
||||
|
||||
override fun onEmojiDownloadComplete(emojiNotifyInfo: EmojiNotifyInfo?) {
|
||||
|
||||
}
|
||||
|
||||
override fun onEmojiResourceUpdate(emojiResourceInfo: EmojiResourceInfo?) {
|
||||
|
||||
}
|
||||
|
||||
override fun onFeedEventUpdate(firstViewDirectMsgNotifyInfo: FirstViewDirectMsgNotifyInfo?) {
|
||||
|
||||
}
|
||||
|
||||
override fun onFileMsgCome(arrayList: ArrayList<MsgRecord>?) {
|
||||
|
||||
}
|
||||
|
||||
override fun onFirstViewDirectMsgUpdate(firstViewDirectMsgNotifyInfo: FirstViewDirectMsgNotifyInfo?) {
|
||||
|
||||
}
|
||||
|
||||
override fun onFirstViewGroupGuildMapping(arrayList: ArrayList<FirstViewGroupGuildInfo>?) {
|
||||
|
||||
}
|
||||
|
||||
override fun onGrabPasswordRedBag(
|
||||
i2: Int,
|
||||
str: String?,
|
||||
i3: Int,
|
||||
recvdOrder: RecvdOrder?,
|
||||
msgRecord: MsgRecord?
|
||||
) {
|
||||
|
||||
}
|
||||
|
||||
override fun onKickedOffLine(kickedInfo: KickedInfo?) {
|
||||
LogCenter.log("onKickedOffLine($kickedInfo)")
|
||||
}
|
||||
|
||||
override fun onRichMediaUploadComplete(notifyInfo: FileTransNotifyInfo) {
|
||||
LogCenter.log({ "[BDH] 资源上传完成(${notifyInfo.trasferStatus}, ${notifyInfo.fileId}, ${notifyInfo.msgId}, ${notifyInfo.commonFileInfo})" }, Level.DEBUG)
|
||||
}
|
||||
|
||||
override fun onRecvOnlineFileMsg(arrayList: ArrayList<MsgRecord>?) {
|
||||
LogCenter.log(("onRecvOnlineFileMsg" + arrayList?.joinToString { ", " }), Level.DEBUG)
|
||||
}
|
||||
|
||||
override fun onRichMediaDownloadComplete(fileTransNotifyInfo: FileTransNotifyInfo) {
|
||||
|
||||
}
|
||||
|
||||
override fun onRichMediaProgerssUpdate(fileTransNotifyInfo: FileTransNotifyInfo) {
|
||||
|
||||
}
|
||||
|
||||
override fun onSearchGroupFileInfoUpdate(searchGroupFileResult: SearchGroupFileResult?) {
|
||||
LogCenter.log("onSearchGroupFileInfoUpdate($searchGroupFileResult)", Level.DEBUG)
|
||||
}
|
||||
|
||||
override fun onGroupFileInfoAdd(groupItem: GroupItem?) {
|
||||
LogCenter.log("onGroupFileInfoAdd: " + groupItem.toString(), Level.DEBUG)
|
||||
}
|
||||
|
||||
override fun onGroupFileInfoUpdate(groupFileListResult: GroupFileListResult?) {
|
||||
LogCenter.log("onGroupFileInfoUpdate: " + groupFileListResult.toString(), Level.DEBUG)
|
||||
}
|
||||
|
||||
override fun onGroupGuildUpdate(groupGuildNotifyInfo: GroupGuildNotifyInfo?) {
|
||||
LogCenter.log("onGroupGuildUpdate: " + groupGuildNotifyInfo.toString(), Level.DEBUG)
|
||||
}
|
||||
|
||||
override fun onGroupTransferInfoAdd(groupItem: GroupItem?) {
|
||||
LogCenter.log("onGroupTransferInfoAdd: " + groupItem.toString(), Level.DEBUG)
|
||||
}
|
||||
|
||||
override fun onGroupTransferInfoUpdate(groupFileListResult: GroupFileListResult?) {
|
||||
LogCenter.log("onGroupTransferInfoUpdate: " + groupFileListResult.toString(), Level.DEBUG)
|
||||
}
|
||||
|
||||
override fun onGuildInteractiveUpdate(guildInteractiveNotificationItem: GuildInteractiveNotificationItem?) {
|
||||
|
||||
}
|
||||
|
||||
override fun onGuildMsgAbFlagChanged(guildMsgAbFlag: GuildMsgAbFlag?) {
|
||||
|
||||
}
|
||||
|
||||
override fun onGuildNotificationAbstractUpdate(guildNotificationAbstractInfo: GuildNotificationAbstractInfo?) {
|
||||
|
||||
}
|
||||
|
||||
override fun onHitCsRelatedEmojiResult(downloadRelateEmojiResultInfo: DownloadRelateEmojiResultInfo?) {
|
||||
|
||||
}
|
||||
|
||||
override fun onHitEmojiKeywordResult(hitRelatedEmojiWordsResult: HitRelatedEmojiWordsResult?) {
|
||||
|
||||
}
|
||||
|
||||
override fun onHitRelatedEmojiResult(relatedWordEmojiInfo: RelatedWordEmojiInfo?) {
|
||||
|
||||
}
|
||||
|
||||
override fun onImportOldDbProgressUpdate(importOldDbMsgNotifyInfo: ImportOldDbMsgNotifyInfo?) {
|
||||
|
||||
}
|
||||
|
||||
override fun onInputStatusPush(inputStatusInfo: InputStatusInfo?) {
|
||||
|
||||
}
|
||||
|
||||
override fun onLineDev(devList: ArrayList<DevInfo>?) {
|
||||
//LogCenter.log("onLineDev($arrayList)")
|
||||
}
|
||||
|
||||
override fun onLogLevelChanged(newLevel: Long) {
|
||||
|
||||
}
|
||||
|
||||
override fun onMsgBoxChanged(arrayList: ArrayList<ContactMsgBoxInfo>?) {
|
||||
|
||||
}
|
||||
|
||||
override fun onMsgDelete(contact: Contact?, arrayList: ArrayList<Long>?) {
|
||||
|
||||
}
|
||||
|
||||
override fun onMsgEventListUpdate(hashMap: HashMap<String, ArrayList<Long>>?) {
|
||||
|
||||
}
|
||||
|
||||
override fun onMsgInfoListAdd(arrayList: ArrayList<MsgRecord>?) {
|
||||
|
||||
}
|
||||
|
||||
override fun onMsgQRCodeStatusChanged(i2: Int) {
|
||||
|
||||
}
|
||||
|
||||
override fun onMsgSecurityNotify(msgRecord: MsgRecord?) {
|
||||
LogCenter.log("onMsgSecurityNotify($msgRecord)")
|
||||
}
|
||||
|
||||
override fun onMsgSettingUpdate(msgSetting: MsgSetting?) {
|
||||
|
||||
}
|
||||
|
||||
override fun onNtFirstViewMsgSyncEnd() {
|
||||
|
||||
}
|
||||
|
||||
override fun onNtMsgSyncEnd() {
|
||||
LogCenter.log("NTKernel同步消息完成", Level.DEBUG)
|
||||
}
|
||||
|
||||
override fun onNtMsgSyncStart() {
|
||||
LogCenter.log("NTKernel同步消息开始", Level.DEBUG)
|
||||
}
|
||||
|
||||
override fun onReadFeedEventUpdate(firstViewDirectMsgNotifyInfo: FirstViewDirectMsgNotifyInfo?) {
|
||||
|
||||
}
|
||||
|
||||
override fun onRecvGroupGuildFlag(i2: Int) {
|
||||
|
||||
}
|
||||
|
||||
override fun onRecvUDCFlag(i2: Int) {
|
||||
LogCenter.log("onRecvUDCFlag($i2)", Level.DEBUG)
|
||||
}
|
||||
|
||||
override fun onSendMsgError(j2: Long, contact: Contact?, i2: Int, str: String?) {
|
||||
LogCenter.log("onSendMsgError($j2, $contact, $j2, $str)", Level.DEBUG)
|
||||
}
|
||||
|
||||
override fun onSysMsgNotification(i2: Int, j2: Long, j3: Long, arrayList: ArrayList<Byte>?) {
|
||||
LogCenter.log("onSysMsgNotification($i2, $j2, $j3, $arrayList)", Level.DEBUG)
|
||||
}
|
||||
|
||||
override fun onUnreadCntAfterFirstView(hashMap: HashMap<Int, ArrayList<UnreadCntInfo>>?) {
|
||||
|
||||
}
|
||||
|
||||
override fun onUnreadCntUpdate(hashMap: HashMap<Int, ArrayList<UnreadCntInfo>>?) {
|
||||
|
||||
}
|
||||
|
||||
override fun onUserChannelTabStatusChanged(z: Boolean) {
|
||||
|
||||
}
|
||||
|
||||
override fun onUserOnlineStatusChanged(z: Boolean) {
|
||||
|
||||
}
|
||||
|
||||
override fun onUserTabStatusChanged(arrayList: ArrayList<TabStatusInfo>?) {
|
||||
LogCenter.log("onUserTabStatusChanged($arrayList)", Level.DEBUG)
|
||||
}
|
||||
|
||||
override fun onlineStatusBigIconDownloadPush(i2: Int, j2: Long, str: String?) {
|
||||
|
||||
}
|
||||
|
||||
override fun onlineStatusSmallIconDownloadPush(i2: Int, j2: Long, str: String?) {
|
||||
|
||||
}
|
||||
}
|
@ -4,6 +4,8 @@ import com.tencent.qphone.base.remote.FromServiceMsg
|
||||
import com.tencent.qphone.base.remote.ToServiceMsg
|
||||
import kotlinx.coroutines.sync.Mutex
|
||||
import kotlinx.coroutines.sync.withLock
|
||||
import moe.fuqiuluo.shamrock.helper.Level
|
||||
import moe.fuqiuluo.shamrock.helper.LogCenter
|
||||
|
||||
typealias MsfPush = (FromServiceMsg) -> Unit
|
||||
typealias MsfResp = (ToServiceMsg, FromServiceMsg) -> Unit
|
||||
@ -45,8 +47,13 @@ internal object MSFHandler {
|
||||
}
|
||||
|
||||
fun onResp(toServiceMsg: ToServiceMsg, fromServiceMsg: FromServiceMsg) {
|
||||
val cmd = toServiceMsg.getAttribute("respkey") as Int
|
||||
runCatching {
|
||||
val cmd = toServiceMsg.getAttribute("shamrock_uid") as? Int?
|
||||
?: return@runCatching
|
||||
val resp = mRespHandler[cmd]
|
||||
resp?.invoke(toServiceMsg, fromServiceMsg)
|
||||
}.onFailure {
|
||||
LogCenter.log("MSF.onResp failed: ${it.message}", Level.ERROR)
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user