mirror of
https://github.com/whitechi73/OpenShamrock.git
synced 2024-08-14 13:12:17 +08:00
fix kritor
This commit is contained in:
parent
b6a510ce05
commit
ad313f384c
4
.gitmodules
vendored
4
.gitmodules
vendored
@ -1,3 +1,3 @@
|
|||||||
[submodule "kritor"]
|
[submodule "kritor"]
|
||||||
path = kritor
|
path = kritor/kritor
|
||||||
url = https://github.com/KarinJS/kritor-kotlin
|
url = https://github.com/KarinJS/kritor
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
package kritor.service
|
package kritor.service
|
||||||
|
|
||||||
import kotlin.reflect.KClass
|
|
||||||
|
|
||||||
@Retention(AnnotationRetention.SOURCE)
|
@Retention(AnnotationRetention.SOURCE)
|
||||||
@Target(AnnotationTarget.FUNCTION)
|
@Target(AnnotationTarget.FUNCTION)
|
||||||
annotation class Grpc(
|
annotation class Grpc(
|
||||||
|
@ -1,8 +0,0 @@
|
|||||||
package moe.fuqiuluo.symbols
|
|
||||||
|
|
||||||
@Retention(AnnotationRetention.SOURCE)
|
|
||||||
@Target(AnnotationTarget.CLASS)
|
|
||||||
annotation class OneBotHandler(
|
|
||||||
val actionName: String,
|
|
||||||
val alias: Array<String> = []
|
|
||||||
)
|
|
@ -1,5 +1,5 @@
|
|||||||
plugins {
|
plugins {
|
||||||
kotlin("jvm") version "1.9.21"
|
kotlin("jvm") version "1.9.22"
|
||||||
}
|
}
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
|
@ -15,8 +15,9 @@ fun ktor(target: String, name: String): String {
|
|||||||
return "io.ktor:ktor-$target-$name:${Versions.ktorVersion}"
|
return "io.ktor:ktor-$target-$name:${Versions.ktorVersion}"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun grpc(name: String, version: String) = "io.grpc:grpc-$name:$version"
|
||||||
|
|
||||||
object Versions {
|
object Versions {
|
||||||
const val roomVersion = "2.5.0"
|
const val roomVersion = "2.5.0"
|
||||||
|
|
||||||
const val ktorVersion = "2.3.3"
|
const val ktorVersion = "2.3.3"
|
||||||
}
|
}
|
1
kritor
1
kritor
@ -1 +0,0 @@
|
|||||||
Subproject commit 10dca646c83d1ef45deab0ac4ab2d80446e902cf
|
|
42
kritor/.gitignore
vendored
Normal file
42
kritor/.gitignore
vendored
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
.gradle
|
||||||
|
build/
|
||||||
|
!gradle/wrapper/gradle-wrapper.jar
|
||||||
|
!**/src/main/**/build/
|
||||||
|
!**/src/test/**/build/
|
||||||
|
|
||||||
|
### IntelliJ IDEA ###
|
||||||
|
.idea/modules.xml
|
||||||
|
.idea/jarRepositories.xml
|
||||||
|
.idea/compiler.xml
|
||||||
|
.idea/libraries/
|
||||||
|
*.iws
|
||||||
|
*.iml
|
||||||
|
*.ipr
|
||||||
|
out/
|
||||||
|
!**/src/main/**/out/
|
||||||
|
!**/src/test/**/out/
|
||||||
|
|
||||||
|
### Eclipse ###
|
||||||
|
.apt_generated
|
||||||
|
.classpath
|
||||||
|
.factorypath
|
||||||
|
.project
|
||||||
|
.settings
|
||||||
|
.springBeans
|
||||||
|
.sts4-cache
|
||||||
|
bin/
|
||||||
|
!**/src/main/**/bin/
|
||||||
|
!**/src/test/**/bin/
|
||||||
|
|
||||||
|
### NetBeans ###
|
||||||
|
/nbproject/private/
|
||||||
|
/nbbuild/
|
||||||
|
/dist/
|
||||||
|
/nbdist/
|
||||||
|
/.nb-gradle/
|
||||||
|
|
||||||
|
### VS Code ###
|
||||||
|
.vscode/
|
||||||
|
|
||||||
|
### Mac OS ###
|
||||||
|
.DS_Store
|
75
kritor/build.gradle.kts
Normal file
75
kritor/build.gradle.kts
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
||||||
|
|
||||||
|
plugins {
|
||||||
|
id("com.android.library")
|
||||||
|
id("org.jetbrains.kotlin.android")
|
||||||
|
id("com.google.protobuf") version "0.9.4"
|
||||||
|
}
|
||||||
|
|
||||||
|
android {
|
||||||
|
namespace = "moe.whitechi73.kritor"
|
||||||
|
compileSdk = 34
|
||||||
|
|
||||||
|
defaultConfig {
|
||||||
|
minSdk = 24
|
||||||
|
|
||||||
|
consumerProguardFiles("consumer-rules.pro")
|
||||||
|
}
|
||||||
|
|
||||||
|
buildTypes {
|
||||||
|
release {
|
||||||
|
isMinifyEnabled = false
|
||||||
|
proguardFiles(
|
||||||
|
getDefaultProguardFile("proguard-android-optimize.txt"),
|
||||||
|
"proguard-rules.pro"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
compileOptions {
|
||||||
|
sourceCompatibility = JavaVersion.VERSION_1_8
|
||||||
|
targetCompatibility = JavaVersion.VERSION_1_8
|
||||||
|
}
|
||||||
|
kotlinOptions {
|
||||||
|
jvmTarget = "1.8"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
protobuf(files("kritor/protos"))
|
||||||
|
|
||||||
|
implementation(kotlinx("coroutines-core", "1.8.0"))
|
||||||
|
implementation("com.google.protobuf:protobuf-java:3.25.3")
|
||||||
|
|
||||||
|
implementation(grpc("stub", "1.62.2"))
|
||||||
|
implementation(grpc("kotlin-stub", "1.4.1"))
|
||||||
|
implementation(grpc("protobuf", "1.62.2"))
|
||||||
|
}
|
||||||
|
|
||||||
|
protobuf {
|
||||||
|
protoc {
|
||||||
|
artifact = "com.google.protobuf:protoc:3.25.3"
|
||||||
|
}
|
||||||
|
plugins {
|
||||||
|
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("grpc")
|
||||||
|
create("grpckt")
|
||||||
|
}
|
||||||
|
it.builtins {
|
||||||
|
create("java")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks.withType<KotlinCompile>().configureEach {
|
||||||
|
kotlinOptions.freeCompilerArgs += "-opt-in=kotlin.RequiresOptIn"
|
||||||
|
}
|
0
kritor/consumer-rules.pro
Normal file
0
kritor/consumer-rules.pro
Normal file
1
kritor/kritor
Submodule
1
kritor/kritor
Submodule
@ -0,0 +1 @@
|
|||||||
|
Subproject commit 94f2e74b79b003685f785336a279d2cc75f95829
|
21
kritor/proguard-rules.pro
vendored
Normal file
21
kritor/proguard-rules.pro
vendored
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
# Add project specific ProGuard rules here.
|
||||||
|
# You can control the set of applied configuration files using the
|
||||||
|
# proguardFiles setting in build.gradle.
|
||||||
|
#
|
||||||
|
# For more details, see
|
||||||
|
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||||
|
|
||||||
|
# If your project uses WebView with JS, uncomment the following
|
||||||
|
# and specify the fully qualified class name to the JavaScript interface
|
||||||
|
# class:
|
||||||
|
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||||
|
# public *;
|
||||||
|
#}
|
||||||
|
|
||||||
|
# Uncomment this to preserve the line number information for
|
||||||
|
# debugging stack traces.
|
||||||
|
#-keepattributes SourceFile,LineNumberTable
|
||||||
|
|
||||||
|
# If you keep the line number information, uncomment this to
|
||||||
|
# hide the original source file name.
|
||||||
|
#-renamesourcefileattribute SourceFile
|
@ -37,7 +37,6 @@ android {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
//implementation(DEPENDENCY_PROTOBUF)
|
|
||||||
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"))
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@ data class ButtonExtra(
|
|||||||
@Serializable
|
@Serializable
|
||||||
data class Object1(
|
data class Object1(
|
||||||
@ProtoNumber(1) val rows: List<Row>? = null,
|
@ProtoNumber(1) val rows: List<Row>? = null,
|
||||||
@ProtoNumber(2) val appid: Int? = null,
|
@ProtoNumber(2) val appid: ULong? = null,
|
||||||
)
|
)
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
|
@ -26,7 +26,7 @@ buildscript {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath("com.android.tools:r8:8.2.47")
|
classpath("com.android.tools:r8:8.3.37")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -34,11 +34,9 @@ rootProject.name = "Shamrock"
|
|||||||
include(
|
include(
|
||||||
":app",
|
":app",
|
||||||
":xposed",
|
":xposed",
|
||||||
":qqinterface"
|
":qqinterface",
|
||||||
|
":protobuf",
|
||||||
|
":processor",
|
||||||
|
":annotations",
|
||||||
|
":kritor"
|
||||||
)
|
)
|
||||||
include(":protobuf")
|
|
||||||
include(":processor")
|
|
||||||
include(":annotations")
|
|
||||||
include(":kritor")
|
|
||||||
|
|
||||||
project(":kritor").projectDir = file("kritor/protos")
|
|
@ -5,7 +5,6 @@ plugins {
|
|||||||
id("org.jetbrains.kotlin.android")
|
id("org.jetbrains.kotlin.android")
|
||||||
id("kotlin-kapt")
|
id("kotlin-kapt")
|
||||||
id("com.google.devtools.ksp") version "1.9.22-1.0.17"
|
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"
|
kotlin("plugin.serialization") version "1.9.22"
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -64,8 +63,7 @@ dependencies {
|
|||||||
compileOnly("de.robv.android.xposed:api:82")
|
compileOnly("de.robv.android.xposed:api:82")
|
||||||
compileOnly(project(":qqinterface"))
|
compileOnly(project(":qqinterface"))
|
||||||
|
|
||||||
protobuf(project(":kritor"))
|
implementation(project(":kritor"))
|
||||||
|
|
||||||
implementation(project(":protobuf"))
|
implementation(project(":protobuf"))
|
||||||
implementation(project(":annotations"))
|
implementation(project(":annotations"))
|
||||||
ksp(project(":processor"))
|
ksp(project(":processor"))
|
||||||
@ -75,24 +73,20 @@ dependencies {
|
|||||||
DEPENDENCY_ANDROIDX.forEach {
|
DEPENDENCY_ANDROIDX.forEach {
|
||||||
implementation(it)
|
implementation(it)
|
||||||
}
|
}
|
||||||
//implementation(DEPENDENCY_PROTOBUF)
|
|
||||||
|
|
||||||
implementation(room("runtime"))
|
implementation(room("runtime"))
|
||||||
kapt(room("compiler"))
|
kapt(room("compiler"))
|
||||||
implementation(room("ktx"))
|
implementation(room("ktx"))
|
||||||
|
|
||||||
implementation(kotlinx("io-jvm", "0.1.16"))
|
implementation(kotlinx("io-jvm", "0.1.16"))
|
||||||
implementation(kotlinx("serialization-protobuf", "1.6.2"))
|
|
||||||
|
|
||||||
implementation(ktor("client", "core"))
|
implementation(ktor("client", "core"))
|
||||||
implementation(ktor("client", "okhttp"))
|
implementation(ktor("client", "okhttp"))
|
||||||
implementation(ktor("serialization", "kotlinx-json"))
|
implementation(ktor("serialization", "kotlinx-json"))
|
||||||
|
|
||||||
implementation("io.grpc:grpc-stub:1.62.2")
|
implementation(grpc("protobuf", "1.62.2"))
|
||||||
implementation("io.grpc:grpc-protobuf-lite:1.62.2")
|
implementation(grpc("kotlin-stub", "1.4.1"))
|
||||||
implementation("com.google.protobuf:protobuf-kotlin-lite:3.25.3")
|
implementation(grpc("okhttp", "1.62.2"))
|
||||||
implementation("io.grpc:grpc-kotlin-stub:1.4.1")
|
|
||||||
implementation("io.grpc:grpc-okhttp:1.62.2")
|
|
||||||
|
|
||||||
testImplementation("junit:junit:4.13.2")
|
testImplementation("junit:junit:4.13.2")
|
||||||
androidTestImplementation("androidx.test.ext:junit:1.1.5")
|
androidTestImplementation("androidx.test.ext:junit:1.1.5")
|
||||||
@ -106,40 +100,3 @@ tasks.withType<KotlinCompile>().all {
|
|||||||
freeCompilerArgs = listOf("-opt-in=kotlin.RequiresOptIn")
|
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")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -5,10 +5,7 @@ import com.google.protobuf.ByteString
|
|||||||
import io.grpc.ManagedChannel
|
import io.grpc.ManagedChannel
|
||||||
import io.grpc.ManagedChannelBuilder
|
import io.grpc.ManagedChannelBuilder
|
||||||
import io.kritor.ReverseServiceGrpcKt
|
import io.kritor.ReverseServiceGrpcKt
|
||||||
import io.kritor.event.EventServiceGrpcKt
|
import io.kritor.event.*
|
||||||
import io.kritor.event.EventType
|
|
||||||
import io.kritor.event.eventStructure
|
|
||||||
import io.kritor.event.messageEvent
|
|
||||||
import io.kritor.reverse.ReqCode
|
import io.kritor.reverse.ReqCode
|
||||||
import io.kritor.reverse.Request
|
import io.kritor.reverse.Request
|
||||||
import io.kritor.reverse.Response
|
import io.kritor.reverse.Response
|
||||||
@ -83,23 +80,23 @@ internal class KritorClient(
|
|||||||
EventServiceGrpcKt.EventServiceCoroutineStub(channel).registerPassiveListener(channelFlow {
|
EventServiceGrpcKt.EventServiceCoroutineStub(channel).registerPassiveListener(channelFlow {
|
||||||
when(eventType) {
|
when(eventType) {
|
||||||
EventType.EVENT_TYPE_MESSAGE -> GlobalEventTransmitter.onMessageEvent {
|
EventType.EVENT_TYPE_MESSAGE -> GlobalEventTransmitter.onMessageEvent {
|
||||||
send(eventStructure {
|
send(EventStructure.newBuilder().apply {
|
||||||
this.type = EventType.EVENT_TYPE_MESSAGE
|
this.type = EventType.EVENT_TYPE_MESSAGE
|
||||||
this.message = it.second
|
this.message = it.second
|
||||||
})
|
}.build())
|
||||||
}
|
}
|
||||||
EventType.EVENT_TYPE_CORE_EVENT -> {}
|
EventType.EVENT_TYPE_CORE_EVENT -> {}
|
||||||
EventType.EVENT_TYPE_NOTICE -> GlobalEventTransmitter.onNoticeEvent {
|
EventType.EVENT_TYPE_NOTICE -> GlobalEventTransmitter.onNoticeEvent {
|
||||||
send(eventStructure {
|
send(EventStructure.newBuilder().apply {
|
||||||
this.type = EventType.EVENT_TYPE_NOTICE
|
this.type = EventType.EVENT_TYPE_NOTICE
|
||||||
this.notice = it
|
this.notice = it
|
||||||
})
|
}.build())
|
||||||
}
|
}
|
||||||
EventType.EVENT_TYPE_REQUEST -> GlobalEventTransmitter.onRequestEvent {
|
EventType.EVENT_TYPE_REQUEST -> GlobalEventTransmitter.onRequestEvent {
|
||||||
send(eventStructure {
|
send(EventStructure.newBuilder().apply {
|
||||||
this.type = EventType.EVENT_TYPE_REQUEST
|
this.type = EventType.EVENT_TYPE_REQUEST
|
||||||
this.request = it
|
this.request = it
|
||||||
})
|
}.build())
|
||||||
}
|
}
|
||||||
EventType.UNRECOGNIZED -> {}
|
EventType.UNRECOGNIZED -> {}
|
||||||
}
|
}
|
||||||
|
@ -8,8 +8,6 @@ import io.kritor.AuthRsp
|
|||||||
import io.kritor.AuthenticationGrpcKt
|
import io.kritor.AuthenticationGrpcKt
|
||||||
import io.kritor.GetAuthStateReq
|
import io.kritor.GetAuthStateReq
|
||||||
import io.kritor.GetAuthStateRsp
|
import io.kritor.GetAuthStateRsp
|
||||||
import io.kritor.authRsp
|
|
||||||
import io.kritor.getAuthStateRsp
|
|
||||||
import kritor.auth.AuthInterceptor
|
import kritor.auth.AuthInterceptor
|
||||||
import moe.fuqiuluo.shamrock.config.ActiveTicket
|
import moe.fuqiuluo.shamrock.config.ActiveTicket
|
||||||
import moe.fuqiuluo.shamrock.config.ShamrockConfig
|
import moe.fuqiuluo.shamrock.config.ShamrockConfig
|
||||||
@ -19,10 +17,10 @@ internal object Authentication: AuthenticationGrpcKt.AuthenticationCoroutineImpl
|
|||||||
@Grpc("Authentication", "Auth")
|
@Grpc("Authentication", "Auth")
|
||||||
override suspend fun auth(request: AuthReq): AuthRsp {
|
override suspend fun auth(request: AuthReq): AuthRsp {
|
||||||
if (QQInterfaces.app.account != request.account) {
|
if (QQInterfaces.app.account != request.account) {
|
||||||
return authRsp {
|
return AuthRsp.newBuilder().apply {
|
||||||
code = AuthCode.NO_ACCOUNT
|
code = AuthCode.NO_ACCOUNT
|
||||||
msg = "No such account"
|
msg = "No such account"
|
||||||
}
|
}.build()
|
||||||
}
|
}
|
||||||
|
|
||||||
val activeTicketName = ActiveTicket.name()
|
val activeTicketName = ActiveTicket.name()
|
||||||
@ -31,26 +29,26 @@ internal object Authentication: AuthenticationGrpcKt.AuthenticationCoroutineImpl
|
|||||||
val ticket = ShamrockConfig.getProperty(activeTicketName + if (index == 0) "" else ".$index", null)
|
val ticket = ShamrockConfig.getProperty(activeTicketName + if (index == 0) "" else ".$index", null)
|
||||||
if (ticket.isNullOrEmpty()) {
|
if (ticket.isNullOrEmpty()) {
|
||||||
if (index == 0) {
|
if (index == 0) {
|
||||||
return authRsp {
|
return AuthRsp.newBuilder().apply {
|
||||||
code = AuthCode.OK
|
code = AuthCode.OK
|
||||||
msg = "OK"
|
msg = "OK"
|
||||||
}
|
}.build()
|
||||||
} else {
|
} else {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
} else if (ticket == request.ticket) {
|
} else if (ticket == request.ticket) {
|
||||||
return authRsp {
|
return AuthRsp.newBuilder().apply {
|
||||||
code = AuthCode.OK
|
code = AuthCode.OK
|
||||||
msg = "OK"
|
msg = "OK"
|
||||||
}
|
}.build()
|
||||||
}
|
}
|
||||||
index++
|
index++
|
||||||
}
|
}
|
||||||
|
|
||||||
return authRsp {
|
return AuthRsp.newBuilder().apply {
|
||||||
code = AuthCode.NO_TICKET
|
code = AuthCode.NO_TICKET
|
||||||
msg = "Invalid ticket"
|
msg = "Invalid ticket"
|
||||||
}
|
}.build()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Grpc("Authentication", "GetAuthState")
|
@Grpc("Authentication", "GetAuthState")
|
||||||
@ -59,8 +57,8 @@ internal object Authentication: AuthenticationGrpcKt.AuthenticationCoroutineImpl
|
|||||||
throw StatusRuntimeException(Status.CANCELLED.withDescription("No such account"))
|
throw StatusRuntimeException(Status.CANCELLED.withDescription("No such account"))
|
||||||
}
|
}
|
||||||
|
|
||||||
return getAuthStateRsp {
|
return GetAuthStateRsp.newBuilder().apply {
|
||||||
isRequiredAuth = AuthInterceptor.getAllTicket().isNotEmpty()
|
isRequiredAuth = AuthInterceptor.getAllTicket().isNotEmpty()
|
||||||
}
|
}.build()
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -23,31 +23,31 @@ import io.kritor.contact.StrangerInfo
|
|||||||
import io.kritor.contact.StrangerInfoRequest
|
import io.kritor.contact.StrangerInfoRequest
|
||||||
import io.kritor.contact.VoteUserRequest
|
import io.kritor.contact.VoteUserRequest
|
||||||
import io.kritor.contact.VoteUserResponse
|
import io.kritor.contact.VoteUserResponse
|
||||||
import io.kritor.contact.profileCard
|
|
||||||
import io.kritor.contact.strangerInfo
|
|
||||||
import io.kritor.contact.voteUserResponse
|
|
||||||
import kotlinx.coroutines.suspendCancellableCoroutine
|
import kotlinx.coroutines.suspendCancellableCoroutine
|
||||||
import kotlinx.coroutines.withTimeoutOrNull
|
import kotlinx.coroutines.withTimeoutOrNull
|
||||||
import qq.service.QQInterfaces
|
import qq.service.QQInterfaces
|
||||||
import qq.service.contact.ContactHelper
|
import qq.service.contact.ContactHelper
|
||||||
import kotlin.coroutines.resume
|
import kotlin.coroutines.resume
|
||||||
import kotlin.coroutines.suspendCoroutine
|
|
||||||
|
|
||||||
internal object ContactService : ContactServiceGrpcKt.ContactServiceCoroutineImplBase() {
|
internal object ContactService : ContactServiceGrpcKt.ContactServiceCoroutineImplBase() {
|
||||||
@Grpc("ContactService", "VoteUser")
|
@Grpc("ContactService", "VoteUser")
|
||||||
override suspend fun voteUser(request: VoteUserRequest): VoteUserResponse {
|
override suspend fun voteUser(request: VoteUserRequest): VoteUserResponse {
|
||||||
ContactHelper.voteUser(when(request.accountCase!!) {
|
ContactHelper.voteUser(
|
||||||
|
when (request.accountCase!!) {
|
||||||
VoteUserRequest.AccountCase.ACCOUNT_UIN -> request.accountUin
|
VoteUserRequest.AccountCase.ACCOUNT_UIN -> request.accountUin
|
||||||
VoteUserRequest.AccountCase.ACCOUNT_UID -> ContactHelper.getUinByUidAsync(request.accountUid).toLong()
|
VoteUserRequest.AccountCase.ACCOUNT_UID -> ContactHelper.getUinByUidAsync(request.accountUid).toLong()
|
||||||
VoteUserRequest.AccountCase.ACCOUNT_NOT_SET -> throw StatusRuntimeException(Status.INVALID_ARGUMENT
|
VoteUserRequest.AccountCase.ACCOUNT_NOT_SET -> throw StatusRuntimeException(
|
||||||
|
Status.INVALID_ARGUMENT
|
||||||
.withDescription("account not set")
|
.withDescription("account not set")
|
||||||
)
|
)
|
||||||
}, request.voteCount).onFailure {
|
}, request.voteCount
|
||||||
throw StatusRuntimeException(Status.INTERNAL
|
).onFailure {
|
||||||
|
throw StatusRuntimeException(
|
||||||
|
Status.INTERNAL
|
||||||
.withDescription(it.stackTraceToString())
|
.withDescription(it.stackTraceToString())
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
return voteUserResponse { }
|
return VoteUserResponse.newBuilder().build()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Grpc("ContactService", "GetProfileCard")
|
@Grpc("ContactService", "GetProfileCard")
|
||||||
@ -55,7 +55,8 @@ internal object ContactService: ContactServiceGrpcKt.ContactServiceCoroutineImpl
|
|||||||
val uin = when (request.accountCase!!) {
|
val uin = when (request.accountCase!!) {
|
||||||
ProfileCardRequest.AccountCase.ACCOUNT_UIN -> request.accountUin
|
ProfileCardRequest.AccountCase.ACCOUNT_UIN -> request.accountUin
|
||||||
ProfileCardRequest.AccountCase.ACCOUNT_UID -> ContactHelper.getUinByUidAsync(request.accountUid).toLong()
|
ProfileCardRequest.AccountCase.ACCOUNT_UID -> ContactHelper.getUinByUidAsync(request.accountUid).toLong()
|
||||||
ProfileCardRequest.AccountCase.ACCOUNT_NOT_SET -> throw StatusRuntimeException(Status.INVALID_ARGUMENT
|
ProfileCardRequest.AccountCase.ACCOUNT_NOT_SET -> throw StatusRuntimeException(
|
||||||
|
Status.INVALID_ARGUMENT
|
||||||
.withDescription("account not set")
|
.withDescription("account not set")
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -63,13 +64,14 @@ internal object ContactService: ContactServiceGrpcKt.ContactServiceCoroutineImpl
|
|||||||
val contact = ContactHelper.getProfileCard(uin)
|
val contact = ContactHelper.getProfileCard(uin)
|
||||||
|
|
||||||
contact.onFailure {
|
contact.onFailure {
|
||||||
throw StatusRuntimeException(Status.INTERNAL
|
throw StatusRuntimeException(
|
||||||
|
Status.INTERNAL
|
||||||
.withDescription(it.stackTraceToString())
|
.withDescription(it.stackTraceToString())
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
contact.onSuccess {
|
contact.onSuccess {
|
||||||
return profileCard {
|
return ProfileCard.newBuilder().apply {
|
||||||
this.uin = it.uin.toLong()
|
this.uin = it.uin.toLong()
|
||||||
this.uid = if (request.hasAccountUid()) request.accountUid
|
this.uid = if (request.hasAccountUid()) request.accountUid
|
||||||
else ContactHelper.getUidByUinAsync(it.uin.toLong())
|
else ContactHelper.getUidByUinAsync(it.uin.toLong())
|
||||||
@ -81,10 +83,11 @@ internal object ContactService: ContactServiceGrpcKt.ContactServiceCoroutineImpl
|
|||||||
this.voteCnt = it.lVoteCount.toInt()
|
this.voteCnt = it.lVoteCount.toInt()
|
||||||
this.qid = it.qid ?: ""
|
this.qid = it.qid ?: ""
|
||||||
this.isSchoolVerified = it.schoolVerifiedFlag
|
this.isSchoolVerified = it.schoolVerifiedFlag
|
||||||
}
|
}.build()
|
||||||
}
|
}
|
||||||
|
|
||||||
throw StatusRuntimeException(Status.INTERNAL
|
throw StatusRuntimeException(
|
||||||
|
Status.INTERNAL
|
||||||
.withDescription("logic failed")
|
.withDescription("logic failed")
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -93,13 +96,14 @@ internal object ContactService: ContactServiceGrpcKt.ContactServiceCoroutineImpl
|
|||||||
override suspend fun getStrangerInfo(request: StrangerInfoRequest): StrangerInfo {
|
override suspend fun getStrangerInfo(request: StrangerInfoRequest): StrangerInfo {
|
||||||
val userId = request.uin
|
val userId = request.uin
|
||||||
val info = ContactHelper.refreshAndGetProfileCard(userId).onFailure {
|
val info = ContactHelper.refreshAndGetProfileCard(userId).onFailure {
|
||||||
throw StatusRuntimeException(Status.INTERNAL
|
throw StatusRuntimeException(
|
||||||
|
Status.INTERNAL
|
||||||
.withCause(it)
|
.withCause(it)
|
||||||
.withDescription("Unable to fetch stranger info")
|
.withDescription("Unable to fetch stranger info")
|
||||||
)
|
)
|
||||||
}.getOrThrow()
|
}.getOrThrow()
|
||||||
|
|
||||||
return strangerInfo {
|
return StrangerInfo.newBuilder().apply {
|
||||||
this.uid = ContactHelper.getUidByUinAsync(userId)
|
this.uid = ContactHelper.getUidByUinAsync(userId)
|
||||||
this.uin = (info.uin ?: "0").toLong()
|
this.uin = (info.uin ?: "0").toLong()
|
||||||
this.name = info.strNick ?: ""
|
this.name = info.strNick ?: ""
|
||||||
@ -108,14 +112,14 @@ internal object ContactService: ContactServiceGrpcKt.ContactServiceCoroutineImpl
|
|||||||
this.voteCnt = info.lVoteCount.toInt()
|
this.voteCnt = info.lVoteCount.toInt()
|
||||||
this.qid = info.qid ?: ""
|
this.qid = info.qid ?: ""
|
||||||
this.isSchoolVerified = info.schoolVerifiedFlag
|
this.isSchoolVerified = info.schoolVerifiedFlag
|
||||||
this.ext = StrangerExt.newBuilder()
|
this.ext = StrangerExt.newBuilder().apply {
|
||||||
.setBigVip(info.bBigClubVipOpen == 1.toByte())
|
this.bigVip = info.bBigClubVipOpen == 1.toByte()
|
||||||
.setHollywoodVip(info.bHollywoodVipOpen == 1.toByte())
|
this.hollywoodVip = info.bHollywoodVipOpen == 1.toByte()
|
||||||
.setQqVip(info.bQQVipOpen == 1.toByte())
|
this.qqVip = info.bQQVipOpen == 1.toByte()
|
||||||
.setSuperVip(info.bSuperQQOpen == 1.toByte())
|
this.superVip = info.bSuperQQOpen == 1.toByte()
|
||||||
.setVoted(info.bVoted == 1.toByte())
|
this.voted = info.bVoted == 1.toByte()
|
||||||
.build().toByteString()
|
}.build().toByteString()
|
||||||
}
|
}.build()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Grpc("ContactService", "GetUid")
|
@Grpc("ContactService", "GetUid")
|
||||||
|
@ -3,40 +3,31 @@ package kritor.service
|
|||||||
import com.google.protobuf.ByteString
|
import com.google.protobuf.ByteString
|
||||||
import com.tencent.mobileqq.fe.FEKit
|
import com.tencent.mobileqq.fe.FEKit
|
||||||
import com.tencent.mobileqq.qsec.qsecdandelionsdk.Dandelion
|
import com.tencent.mobileqq.qsec.qsecdandelionsdk.Dandelion
|
||||||
import io.kritor.developer.DeveloperServiceGrpcKt
|
import io.kritor.developer.*
|
||||||
import io.kritor.developer.EnergyRequest
|
|
||||||
import io.kritor.developer.EnergyResponse
|
|
||||||
import io.kritor.developer.SendPacketRequest
|
|
||||||
import io.kritor.developer.SendPacketResponse
|
|
||||||
import io.kritor.developer.SignRequest
|
|
||||||
import io.kritor.developer.SignResponse
|
|
||||||
import io.kritor.developer.energyResponse
|
|
||||||
import io.kritor.developer.sendPacketResponse
|
|
||||||
import io.kritor.developer.signResponse
|
|
||||||
import qq.service.QQInterfaces
|
import qq.service.QQInterfaces
|
||||||
|
|
||||||
internal object DeveloperService: DeveloperServiceGrpcKt.DeveloperServiceCoroutineImplBase() {
|
internal object DeveloperService: DeveloperServiceGrpcKt.DeveloperServiceCoroutineImplBase() {
|
||||||
@Grpc("DeveloperService", "Sign")
|
@Grpc("DeveloperService", "Sign")
|
||||||
override suspend fun sign(request: SignRequest): SignResponse {
|
override suspend fun sign(request: SignRequest): SignResponse {
|
||||||
return signResponse {
|
return SignResponse.newBuilder().apply {
|
||||||
val result = FEKit.getInstance().getSign(request.command, request.buffer.toByteArray(), request.seq, request.uin)
|
val result = FEKit.getInstance().getSign(request.command, request.buffer.toByteArray(), request.seq, request.uin)
|
||||||
this.sign = ByteString.copyFrom(result.sign)
|
this.sign = ByteString.copyFrom(result.sign)
|
||||||
this.token = ByteString.copyFrom(result.token)
|
this.token = ByteString.copyFrom(result.token)
|
||||||
this.extra = ByteString.copyFrom(result.extra)
|
this.extra = ByteString.copyFrom(result.extra)
|
||||||
}
|
}.build()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Grpc("DeveloperService", "Energy")
|
@Grpc("DeveloperService", "Energy")
|
||||||
override suspend fun energy(request: EnergyRequest): EnergyResponse {
|
override suspend fun energy(request: EnergyRequest): EnergyResponse {
|
||||||
return energyResponse {
|
return EnergyResponse.newBuilder().apply {
|
||||||
this.result = ByteString.copyFrom(Dandelion.getInstance().fly(request.data, request.salt.toByteArray()))
|
this.result = ByteString.copyFrom(Dandelion.getInstance().fly(request.data, request.salt.toByteArray()))
|
||||||
}
|
}.build()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Grpc("DeveloperService", "SendPacket")
|
@Grpc("DeveloperService", "SendPacket")
|
||||||
override suspend fun sendPacket(request: SendPacketRequest): SendPacketResponse {
|
override suspend fun sendPacket(request: SendPacketRequest): SendPacketResponse {
|
||||||
return sendPacketResponse {
|
return SendPacketResponse.newBuilder().apply {
|
||||||
val fromServiceMsg = QQInterfaces.sendBufferAW(request.command, request.isProtobuf, request.requestBuffer.toByteArray())
|
val fromServiceMsg = QQInterfaces.sendBufferAW(request.command, request.isProtobuf, request.requestBuffer.toByteArray())
|
||||||
if (fromServiceMsg?.wupBuffer == null) {
|
if (fromServiceMsg?.wupBuffer == null) {
|
||||||
this.isSuccess = false
|
this.isSuccess = false
|
||||||
@ -44,7 +35,7 @@ internal object DeveloperService: DeveloperServiceGrpcKt.DeveloperServiceCorouti
|
|||||||
this.isSuccess = true
|
this.isSuccess = true
|
||||||
this.responseBuffer = ByteString.copyFrom(fromServiceMsg.wupBuffer)
|
this.responseBuffer = ByteString.copyFrom(fromServiceMsg.wupBuffer)
|
||||||
}
|
}
|
||||||
}
|
}.build()
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -2,12 +2,10 @@ package kritor.service
|
|||||||
|
|
||||||
import io.grpc.Status
|
import io.grpc.Status
|
||||||
import io.grpc.StatusRuntimeException
|
import io.grpc.StatusRuntimeException
|
||||||
import io.kritor.event.EventRequest
|
|
||||||
import io.kritor.event.EventServiceGrpcKt
|
import io.kritor.event.EventServiceGrpcKt
|
||||||
import io.kritor.event.EventStructure
|
import io.kritor.event.EventStructure
|
||||||
import io.kritor.event.EventType
|
import io.kritor.event.EventType
|
||||||
import io.kritor.event.RequestPushEvent
|
import io.kritor.event.RequestPushEvent
|
||||||
import io.kritor.event.eventStructure
|
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
import kotlinx.coroutines.flow.channelFlow
|
import kotlinx.coroutines.flow.channelFlow
|
||||||
import moe.fuqiuluo.shamrock.internals.GlobalEventTransmitter
|
import moe.fuqiuluo.shamrock.internals.GlobalEventTransmitter
|
||||||
@ -18,23 +16,26 @@ internal object EventService: EventServiceGrpcKt.EventServiceCoroutineImplBase()
|
|||||||
when (request.type!!) {
|
when (request.type!!) {
|
||||||
EventType.EVENT_TYPE_CORE_EVENT -> {}
|
EventType.EVENT_TYPE_CORE_EVENT -> {}
|
||||||
EventType.EVENT_TYPE_MESSAGE -> GlobalEventTransmitter.onMessageEvent {
|
EventType.EVENT_TYPE_MESSAGE -> GlobalEventTransmitter.onMessageEvent {
|
||||||
send(eventStructure {
|
send(EventStructure.newBuilder().apply {
|
||||||
this.type = EventType.EVENT_TYPE_MESSAGE
|
this.type = EventType.EVENT_TYPE_MESSAGE
|
||||||
this.message = it.second
|
this.message = it.second
|
||||||
})
|
}.build())
|
||||||
}
|
}
|
||||||
|
|
||||||
EventType.EVENT_TYPE_NOTICE -> GlobalEventTransmitter.onRequestEvent {
|
EventType.EVENT_TYPE_NOTICE -> GlobalEventTransmitter.onRequestEvent {
|
||||||
send(eventStructure {
|
send(EventStructure.newBuilder().apply {
|
||||||
this.type = EventType.EVENT_TYPE_NOTICE
|
this.type = EventType.EVENT_TYPE_NOTICE
|
||||||
this.request = it
|
this.request = it
|
||||||
})
|
}.build())
|
||||||
}
|
}
|
||||||
|
|
||||||
EventType.EVENT_TYPE_REQUEST -> GlobalEventTransmitter.onNoticeEvent {
|
EventType.EVENT_TYPE_REQUEST -> GlobalEventTransmitter.onNoticeEvent {
|
||||||
send(eventStructure {
|
send(EventStructure.newBuilder().apply {
|
||||||
this.type = EventType.EVENT_TYPE_NOTICE
|
this.type = EventType.EVENT_TYPE_NOTICE
|
||||||
this.notice = it
|
this.notice = it
|
||||||
})
|
}.build())
|
||||||
}
|
}
|
||||||
|
|
||||||
EventType.UNRECOGNIZED -> throw StatusRuntimeException(Status.INVALID_ARGUMENT)
|
EventType.UNRECOGNIZED -> throw StatusRuntimeException(Status.INVALID_ARGUMENT)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,27 +1,21 @@
|
|||||||
package kritor.service
|
package kritor.service
|
||||||
|
|
||||||
import com.tencent.qqnt.kernel.nativeinterface.MsgConstant
|
import com.tencent.qqnt.kernel.nativeinterface.MsgConstant
|
||||||
import com.tencent.qqnt.kernel.nativeinterface.MsgElement
|
|
||||||
import io.grpc.Status
|
import io.grpc.Status
|
||||||
import io.grpc.StatusRuntimeException
|
import io.grpc.StatusRuntimeException
|
||||||
import io.kritor.message.Element
|
import io.kritor.event.MessageEvent
|
||||||
import io.kritor.message.ElementType
|
import io.kritor.message.*
|
||||||
import io.kritor.message.ForwardMessageRequest
|
|
||||||
import io.kritor.message.ForwardMessageResponse
|
|
||||||
import io.kritor.message.ForwardMessageServiceGrpcKt
|
|
||||||
import io.kritor.message.Scene
|
|
||||||
import io.kritor.message.element
|
|
||||||
import io.kritor.message.forwardMessageResponse
|
|
||||||
import qq.service.contact.longPeer
|
import qq.service.contact.longPeer
|
||||||
import qq.service.msg.ForwardMessageHelper
|
import qq.service.msg.ForwardMessageHelper
|
||||||
import qq.service.msg.MessageHelper
|
import qq.service.msg.MessageHelper
|
||||||
import qq.service.msg.NtMsgConvertor
|
import qq.service.msg.toKritorResponseMessages
|
||||||
|
|
||||||
internal object ForwardMessageService : ForwardMessageServiceGrpcKt.ForwardMessageServiceCoroutineImplBase() {
|
internal object ForwardMessageService : ForwardMessageServiceGrpcKt.ForwardMessageServiceCoroutineImplBase() {
|
||||||
@Grpc("ForwardMessageService", "ForwardMessage")
|
@Grpc("ForwardMessageService", "UploadForwardMessage")
|
||||||
override suspend fun forwardMessage(request: ForwardMessageRequest): ForwardMessageResponse {
|
override suspend fun uploadForwardMessage(request: UploadForwardMessageRequest): UploadForwardMessageResponse {
|
||||||
val contact = request.contact.let {
|
val contact = request.contact.let {
|
||||||
MessageHelper.generateContact(when(it.scene!!) {
|
MessageHelper.generateContact(
|
||||||
|
when (it.scene!!) {
|
||||||
Scene.GROUP -> MsgConstant.KCHATTYPEGROUP
|
Scene.GROUP -> MsgConstant.KCHATTYPEGROUP
|
||||||
Scene.FRIEND -> MsgConstant.KCHATTYPEC2C
|
Scene.FRIEND -> MsgConstant.KCHATTYPEC2C
|
||||||
Scene.GUILD -> MsgConstant.KCHATTYPEGUILD
|
Scene.GUILD -> MsgConstant.KCHATTYPEGUILD
|
||||||
@ -29,22 +23,63 @@ internal object ForwardMessageService: ForwardMessageServiceGrpcKt.ForwardMessag
|
|||||||
Scene.NEARBY -> MsgConstant.KCHATTYPETEMPC2CFROMUNKNOWN
|
Scene.NEARBY -> MsgConstant.KCHATTYPETEMPC2CFROMUNKNOWN
|
||||||
Scene.STRANGER -> MsgConstant.KCHATTYPETEMPC2CFROMUNKNOWN
|
Scene.STRANGER -> MsgConstant.KCHATTYPETEMPC2CFROMUNKNOWN
|
||||||
Scene.UNRECOGNIZED -> throw StatusRuntimeException(Status.INVALID_ARGUMENT.withDescription("Unrecognized scene"))
|
Scene.UNRECOGNIZED -> throw StatusRuntimeException(Status.INVALID_ARGUMENT.withDescription("Unrecognized scene"))
|
||||||
}, it.peer, it.subPeer)
|
}, it.peer, it.subPeer
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
val forwardMessage = ForwardMessageHelper.uploadMultiMsg(contact.chatType, contact.longPeer().toString(), contact.guildId, request.messagesList).onFailure {
|
val forwardMessage = ForwardMessageHelper.uploadMultiMsg(
|
||||||
|
contact.chatType,
|
||||||
|
contact.longPeer().toString(),
|
||||||
|
contact.guildId,
|
||||||
|
request.messagesList
|
||||||
|
).onFailure {
|
||||||
throw StatusRuntimeException(Status.INTERNAL.withCause(it))
|
throw StatusRuntimeException(Status.INTERNAL.withCause(it))
|
||||||
}.getOrThrow()
|
}.getOrThrow()
|
||||||
|
|
||||||
val uniseq = MessageHelper.generateMsgId(contact.chatType)
|
return UploadForwardMessageResponse.newBuilder().apply {
|
||||||
return forwardMessageResponse {
|
|
||||||
this.messageId = MessageHelper.sendMessage(contact, NtMsgConvertor.convertToNtMsgs(contact, uniseq, arrayListOf(element {
|
|
||||||
this.type = ElementType.FORWARD
|
|
||||||
this.forward = forwardMessage
|
|
||||||
})), request.retryCount, uniseq).onFailure {
|
|
||||||
throw StatusRuntimeException(Status.INTERNAL.withCause(it))
|
|
||||||
}.getOrThrow()
|
|
||||||
this.resId = forwardMessage.id
|
this.resId = forwardMessage.id
|
||||||
}
|
}.build()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Grpc("ForwardMessageService", "DownloadForwardMessage")
|
||||||
|
override suspend fun downloadForwardMessage(request: DownloadForwardMessageRequest): DownloadForwardMessageResponse {
|
||||||
|
return DownloadForwardMessageResponse.newBuilder().apply {
|
||||||
|
this.addAllMessages(
|
||||||
|
MessageHelper.getForwardMsg(request.resId).onFailure {
|
||||||
|
throw StatusRuntimeException(Status.INTERNAL.withCause(it))
|
||||||
|
}.getOrThrow().map { detail ->
|
||||||
|
MessageEvent.newBuilder().apply {
|
||||||
|
this.time = detail.time
|
||||||
|
this.messageId = detail.qqMsgId
|
||||||
|
this.messageSeq = detail.msgSeq
|
||||||
|
this.contact = Contact.newBuilder().apply {
|
||||||
|
this.scene = when (detail.msgType) {
|
||||||
|
MsgConstant.KCHATTYPEC2C -> Scene.FRIEND
|
||||||
|
MsgConstant.KCHATTYPEGROUP -> Scene.GROUP
|
||||||
|
MsgConstant.KCHATTYPEGUILD -> Scene.GUILD
|
||||||
|
MsgConstant.KCHATTYPETEMPC2CFROMGROUP -> Scene.STRANGER_FROM_GROUP
|
||||||
|
MsgConstant.KCHATTYPETEMPC2CFROMUNKNOWN -> Scene.NEARBY
|
||||||
|
else -> Scene.STRANGER
|
||||||
|
}
|
||||||
|
this.peer = detail.peerId.toString()
|
||||||
|
}.build()
|
||||||
|
this.sender = Sender.newBuilder().apply {
|
||||||
|
this.uin = detail.sender.userId
|
||||||
|
this.nick = detail.sender.nickName
|
||||||
|
this.uid = detail.sender.uid
|
||||||
|
}.build()
|
||||||
|
detail.message?.elements?.toKritorResponseMessages(
|
||||||
|
com.tencent.qqnt.kernel.nativeinterface.Contact(
|
||||||
|
detail.msgType,
|
||||||
|
detail.peerId.toString(),
|
||||||
|
null
|
||||||
|
)
|
||||||
|
)?.let {
|
||||||
|
this.addAllElements(it)
|
||||||
|
}
|
||||||
|
}.build()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}.build()
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -2,12 +2,7 @@ package kritor.service
|
|||||||
|
|
||||||
import io.grpc.Status
|
import io.grpc.Status
|
||||||
import io.grpc.StatusRuntimeException
|
import io.grpc.StatusRuntimeException
|
||||||
import io.kritor.friend.FriendServiceGrpcKt
|
import io.kritor.friend.*
|
||||||
import io.kritor.friend.GetFriendListRequest
|
|
||||||
import io.kritor.friend.GetFriendListResponse
|
|
||||||
import io.kritor.friend.friendData
|
|
||||||
import io.kritor.friend.friendExt
|
|
||||||
import io.kritor.friend.getFriendListResponse
|
|
||||||
import qq.service.contact.ContactHelper
|
import qq.service.contact.ContactHelper
|
||||||
import qq.service.friend.FriendHelper
|
import qq.service.friend.FriendHelper
|
||||||
|
|
||||||
@ -20,9 +15,9 @@ internal object FriendService: FriendServiceGrpcKt.FriendServiceCoroutineImplBas
|
|||||||
)
|
)
|
||||||
}.getOrThrow()
|
}.getOrThrow()
|
||||||
|
|
||||||
return getFriendListResponse {
|
return GetFriendListResponse.newBuilder().apply {
|
||||||
friendList.forEach {
|
friendList.forEach {
|
||||||
this.friendList.add(friendData {
|
this.addFriendList(FriendData.newBuilder().apply {
|
||||||
uin = it.uin.toLong()
|
uin = it.uin.toLong()
|
||||||
uid = ContactHelper.getUidByUinAsync(uin)
|
uid = ContactHelper.getUidByUinAsync(uin)
|
||||||
qid = ""
|
qid = ""
|
||||||
@ -32,10 +27,10 @@ internal object FriendService: FriendServiceGrpcKt.FriendServiceCoroutineImplBas
|
|||||||
level = 0
|
level = 0
|
||||||
gender = it.gender.toInt()
|
gender = it.gender.toInt()
|
||||||
groupId = it.groupid
|
groupId = it.groupid
|
||||||
ext = friendExt {}.toByteString()
|
ext = FriendExt.newBuilder().build().toByteString()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}.build()
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -15,7 +15,6 @@ import qq.service.QQInterfaces
|
|||||||
import qq.service.file.GroupFileHelper
|
import qq.service.file.GroupFileHelper
|
||||||
import qq.service.file.GroupFileHelper.getGroupFileSystemInfo
|
import qq.service.file.GroupFileHelper.getGroupFileSystemInfo
|
||||||
import tencent.im.oidb.cmd0x6d6.oidb_0x6d6
|
import tencent.im.oidb.cmd0x6d6.oidb_0x6d6
|
||||||
import tencent.im.oidb.cmd0x6d8.oidb_0x6d8
|
|
||||||
import tencent.im.oidb.oidb_sso
|
import tencent.im.oidb.oidb_sso
|
||||||
|
|
||||||
internal object GroupFileService: GroupFileServiceGrpcKt.GroupFileServiceCoroutineImplBase() {
|
internal object GroupFileService: GroupFileServiceGrpcKt.GroupFileServiceCoroutineImplBase() {
|
||||||
@ -42,10 +41,10 @@ internal object GroupFileService: GroupFileServiceGrpcKt.GroupFileServiceCorouti
|
|||||||
if (rsp.createFolder?.retCode != 0) {
|
if (rsp.createFolder?.retCode != 0) {
|
||||||
throw StatusRuntimeException(Status.INTERNAL.withDescription("unable to create folder: ${rsp.createFolder?.retCode}"))
|
throw StatusRuntimeException(Status.INTERNAL.withDescription("unable to create folder: ${rsp.createFolder?.retCode}"))
|
||||||
}
|
}
|
||||||
return createFolderResponse {
|
return CreateFolderResponse.newBuilder().apply {
|
||||||
this.id = rsp.createFolder?.folderInfo?.folderId ?: ""
|
this.id = rsp.createFolder?.folderInfo?.folderId ?: ""
|
||||||
this.usedSpace = 0
|
this.usedSpace = 0
|
||||||
}
|
}.build()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Grpc("GroupFileService", "DeleteFolder")
|
@Grpc("GroupFileService", "DeleteFolder")
|
||||||
@ -66,7 +65,7 @@ internal object GroupFileService: GroupFileServiceGrpcKt.GroupFileServiceCorouti
|
|||||||
if (rsp.deleteFolder?.retCode != 0) {
|
if (rsp.deleteFolder?.retCode != 0) {
|
||||||
throw StatusRuntimeException(Status.INTERNAL.withDescription("unable to delete folder: ${rsp.deleteFolder?.retCode}"))
|
throw StatusRuntimeException(Status.INTERNAL.withDescription("unable to delete folder: ${rsp.deleteFolder?.retCode}"))
|
||||||
}
|
}
|
||||||
return deleteFolderResponse { }
|
return DeleteFolderResponse.newBuilder().build()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Grpc("GroupFileService", "DeleteFile")
|
@Grpc("GroupFileService", "DeleteFile")
|
||||||
@ -93,7 +92,7 @@ internal object GroupFileService: GroupFileServiceGrpcKt.GroupFileServiceCorouti
|
|||||||
if (rsp.delete_file_rsp.int32_ret_code.get() != 0) {
|
if (rsp.delete_file_rsp.int32_ret_code.get() != 0) {
|
||||||
throw StatusRuntimeException(Status.INTERNAL.withDescription("unable to delete file: ${rsp.delete_file_rsp.int32_ret_code.get()}"))
|
throw StatusRuntimeException(Status.INTERNAL.withDescription("unable to delete file: ${rsp.delete_file_rsp.int32_ret_code.get()}"))
|
||||||
}
|
}
|
||||||
return deleteFileResponse { }
|
return DeleteFileResponse.newBuilder().build()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Grpc("GroupFileService", "RenameFolder")
|
@Grpc("GroupFileService", "RenameFolder")
|
||||||
@ -115,7 +114,7 @@ internal object GroupFileService: GroupFileServiceGrpcKt.GroupFileServiceCorouti
|
|||||||
if (rsp.renameFolder?.retCode != 0) {
|
if (rsp.renameFolder?.retCode != 0) {
|
||||||
throw StatusRuntimeException(Status.INTERNAL.withDescription("unable to rename folder: ${rsp.renameFolder?.retCode}"))
|
throw StatusRuntimeException(Status.INTERNAL.withDescription("unable to rename folder: ${rsp.renameFolder?.retCode}"))
|
||||||
}
|
}
|
||||||
return renameFolderResponse { }
|
return RenameFolderResponse.newBuilder().build()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Grpc("GroupFileService", "GetFileSystemInfo")
|
@Grpc("GroupFileService", "GetFileSystemInfo")
|
||||||
@ -125,11 +124,11 @@ internal object GroupFileService: GroupFileServiceGrpcKt.GroupFileServiceCorouti
|
|||||||
|
|
||||||
@Grpc("GroupFileService", "GetRootFiles")
|
@Grpc("GroupFileService", "GetRootFiles")
|
||||||
override suspend fun getRootFiles(request: GetRootFilesRequest): GetRootFilesResponse {
|
override suspend fun getRootFiles(request: GetRootFilesRequest): GetRootFilesResponse {
|
||||||
return getRootFilesResponse {
|
return GetRootFilesResponse.newBuilder().apply {
|
||||||
val response = GroupFileHelper.getGroupFiles(request.groupId)
|
val response = GroupFileHelper.getGroupFiles(request.groupId)
|
||||||
this.files.addAll(response.filesList)
|
this.addAllFiles(response.filesList)
|
||||||
this.folders.addAll(response.foldersList)
|
this.addAllFolders(response.foldersList)
|
||||||
}
|
}.build()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Grpc("GroupFileService", "GetFiles")
|
@Grpc("GroupFileService", "GetFiles")
|
||||||
|
@ -2,65 +2,7 @@ package kritor.service
|
|||||||
|
|
||||||
import io.grpc.Status
|
import io.grpc.Status
|
||||||
import io.grpc.StatusRuntimeException
|
import io.grpc.StatusRuntimeException
|
||||||
import io.kritor.group.BanMemberRequest
|
import io.kritor.group.*
|
||||||
import io.kritor.group.BanMemberResponse
|
|
||||||
import io.kritor.group.GetGroupHonorRequest
|
|
||||||
import io.kritor.group.GetGroupHonorResponse
|
|
||||||
import io.kritor.group.GetGroupInfoRequest
|
|
||||||
import io.kritor.group.GetGroupInfoResponse
|
|
||||||
import io.kritor.group.GetGroupListRequest
|
|
||||||
import io.kritor.group.GetGroupListResponse
|
|
||||||
import io.kritor.group.GetGroupMemberInfoRequest
|
|
||||||
import io.kritor.group.GetGroupMemberInfoResponse
|
|
||||||
import io.kritor.group.GetGroupMemberListRequest
|
|
||||||
import io.kritor.group.GetGroupMemberListResponse
|
|
||||||
import io.kritor.group.GetNotJoinedGroupInfoRequest
|
|
||||||
import io.kritor.group.GetNotJoinedGroupInfoResponse
|
|
||||||
import io.kritor.group.GetProhibitedUserListRequest
|
|
||||||
import io.kritor.group.GetProhibitedUserListResponse
|
|
||||||
import io.kritor.group.GetRemainCountAtAllRequest
|
|
||||||
import io.kritor.group.GetRemainCountAtAllResponse
|
|
||||||
import io.kritor.group.GroupServiceGrpcKt
|
|
||||||
import io.kritor.group.KickMemberRequest
|
|
||||||
import io.kritor.group.KickMemberResponse
|
|
||||||
import io.kritor.group.LeaveGroupRequest
|
|
||||||
import io.kritor.group.LeaveGroupResponse
|
|
||||||
import io.kritor.group.ModifyGroupNameRequest
|
|
||||||
import io.kritor.group.ModifyGroupNameResponse
|
|
||||||
import io.kritor.group.ModifyGroupRemarkRequest
|
|
||||||
import io.kritor.group.ModifyGroupRemarkResponse
|
|
||||||
import io.kritor.group.ModifyMemberCardRequest
|
|
||||||
import io.kritor.group.ModifyMemberCardResponse
|
|
||||||
import io.kritor.group.PokeMemberRequest
|
|
||||||
import io.kritor.group.PokeMemberResponse
|
|
||||||
import io.kritor.group.SetGroupAdminRequest
|
|
||||||
import io.kritor.group.SetGroupAdminResponse
|
|
||||||
import io.kritor.group.SetGroupUniqueTitleRequest
|
|
||||||
import io.kritor.group.SetGroupUniqueTitleResponse
|
|
||||||
import io.kritor.group.SetGroupWholeBanRequest
|
|
||||||
import io.kritor.group.SetGroupWholeBanResponse
|
|
||||||
import io.kritor.group.banMemberResponse
|
|
||||||
import io.kritor.group.getGroupHonorResponse
|
|
||||||
import io.kritor.group.getGroupInfoResponse
|
|
||||||
import io.kritor.group.getGroupListResponse
|
|
||||||
import io.kritor.group.getGroupMemberInfoResponse
|
|
||||||
import io.kritor.group.getGroupMemberListResponse
|
|
||||||
import io.kritor.group.getNotJoinedGroupInfoResponse
|
|
||||||
import io.kritor.group.getProhibitedUserListResponse
|
|
||||||
import io.kritor.group.getRemainCountAtAllResponse
|
|
||||||
import io.kritor.group.groupHonorInfo
|
|
||||||
import io.kritor.group.groupMemberInfo
|
|
||||||
import io.kritor.group.kickMemberResponse
|
|
||||||
import io.kritor.group.leaveGroupResponse
|
|
||||||
import io.kritor.group.modifyGroupNameResponse
|
|
||||||
import io.kritor.group.modifyGroupRemarkResponse
|
|
||||||
import io.kritor.group.modifyMemberCardResponse
|
|
||||||
import io.kritor.group.notJoinedGroupInfo
|
|
||||||
import io.kritor.group.pokeMemberResponse
|
|
||||||
import io.kritor.group.prohibitedUserInfo
|
|
||||||
import io.kritor.group.setGroupAdminResponse
|
|
||||||
import io.kritor.group.setGroupUniqueTitleResponse
|
|
||||||
import io.kritor.group.setGroupWholeBanResponse
|
|
||||||
import moe.fuqiuluo.shamrock.helper.TroopHonorHelper.decodeHonor
|
import moe.fuqiuluo.shamrock.helper.TroopHonorHelper.decodeHonor
|
||||||
import moe.fuqiuluo.shamrock.tools.ifNullOrEmpty
|
import moe.fuqiuluo.shamrock.tools.ifNullOrEmpty
|
||||||
import qq.service.contact.ContactHelper
|
import qq.service.contact.ContactHelper
|
||||||
@ -70,144 +12,176 @@ internal object GroupService: GroupServiceGrpcKt.GroupServiceCoroutineImplBase()
|
|||||||
@Grpc("GroupService", "BanMember")
|
@Grpc("GroupService", "BanMember")
|
||||||
override suspend fun banMember(request: BanMemberRequest): BanMemberResponse {
|
override suspend fun banMember(request: BanMemberRequest): BanMemberResponse {
|
||||||
if (!GroupHelper.isAdmin(request.groupId.toString())) {
|
if (!GroupHelper.isAdmin(request.groupId.toString())) {
|
||||||
throw StatusRuntimeException(Status.PERMISSION_DENIED
|
throw StatusRuntimeException(
|
||||||
|
Status.PERMISSION_DENIED
|
||||||
.withDescription("You are not admin of this group")
|
.withDescription("You are not admin of this group")
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
GroupHelper.banMember(request.groupId, when(request.targetCase!!) {
|
GroupHelper.banMember(
|
||||||
|
request.groupId, when (request.targetCase!!) {
|
||||||
BanMemberRequest.TargetCase.TARGET_UIN -> request.targetUin
|
BanMemberRequest.TargetCase.TARGET_UIN -> request.targetUin
|
||||||
BanMemberRequest.TargetCase.TARGET_UID -> ContactHelper.getUinByUidAsync(request.targetUid).toLong()
|
BanMemberRequest.TargetCase.TARGET_UID -> ContactHelper.getUinByUidAsync(request.targetUid).toLong()
|
||||||
else -> throw StatusRuntimeException(Status.INVALID_ARGUMENT
|
else -> throw StatusRuntimeException(
|
||||||
|
Status.INVALID_ARGUMENT
|
||||||
.withDescription("target not set")
|
.withDescription("target not set")
|
||||||
)
|
)
|
||||||
}, request.duration)
|
}, request.duration
|
||||||
|
)
|
||||||
|
|
||||||
return banMemberResponse {
|
return BanMemberResponse.newBuilder().apply {
|
||||||
groupId = request.groupId
|
groupId = request.groupId
|
||||||
}
|
}.build()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Grpc("GroupService", "PokeMember", )
|
@Grpc("GroupService", "PokeMember")
|
||||||
override suspend fun pokeMember(request: PokeMemberRequest): PokeMemberResponse {
|
override suspend fun pokeMember(request: PokeMemberRequest): PokeMemberResponse {
|
||||||
GroupHelper.pokeMember(request.groupId, when(request.targetCase!!) {
|
GroupHelper.pokeMember(
|
||||||
|
request.groupId, when (request.targetCase!!) {
|
||||||
PokeMemberRequest.TargetCase.TARGET_UIN -> request.targetUin
|
PokeMemberRequest.TargetCase.TARGET_UIN -> request.targetUin
|
||||||
PokeMemberRequest.TargetCase.TARGET_UID -> ContactHelper.getUinByUidAsync(request.targetUid).toLong()
|
PokeMemberRequest.TargetCase.TARGET_UID -> ContactHelper.getUinByUidAsync(request.targetUid).toLong()
|
||||||
else -> throw StatusRuntimeException(Status.INVALID_ARGUMENT
|
else -> throw StatusRuntimeException(
|
||||||
|
Status.INVALID_ARGUMENT
|
||||||
.withDescription("target not set")
|
.withDescription("target not set")
|
||||||
)
|
)
|
||||||
})
|
}
|
||||||
return pokeMemberResponse { }
|
)
|
||||||
|
return PokeMemberResponse.newBuilder().build()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Grpc("GroupService", "KickMember")
|
@Grpc("GroupService", "KickMember")
|
||||||
override suspend fun kickMember(request: KickMemberRequest): KickMemberResponse {
|
override suspend fun kickMember(request: KickMemberRequest): KickMemberResponse {
|
||||||
if (!GroupHelper.isAdmin(request.groupId.toString())) {
|
if (!GroupHelper.isAdmin(request.groupId.toString())) {
|
||||||
throw StatusRuntimeException(Status.PERMISSION_DENIED
|
throw StatusRuntimeException(
|
||||||
|
Status.PERMISSION_DENIED
|
||||||
.withDescription("You are not admin of this group")
|
.withDescription("You are not admin of this group")
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
GroupHelper.kickMember(request.groupId, request.rejectAddRequest, if (request.hasKickReason()) request.kickReason else "", when(request.targetCase!!) {
|
GroupHelper.kickMember(
|
||||||
|
request.groupId,
|
||||||
|
request.rejectAddRequest,
|
||||||
|
if (request.hasKickReason()) request.kickReason else "",
|
||||||
|
when (request.targetCase!!) {
|
||||||
KickMemberRequest.TargetCase.TARGET_UIN -> request.targetUin
|
KickMemberRequest.TargetCase.TARGET_UIN -> request.targetUin
|
||||||
KickMemberRequest.TargetCase.TARGET_UID -> ContactHelper.getUinByUidAsync(request.targetUid).toLong()
|
KickMemberRequest.TargetCase.TARGET_UID -> ContactHelper.getUinByUidAsync(request.targetUid).toLong()
|
||||||
else -> throw StatusRuntimeException(Status.INVALID_ARGUMENT
|
else -> throw StatusRuntimeException(
|
||||||
|
Status.INVALID_ARGUMENT
|
||||||
.withDescription("target not set")
|
.withDescription("target not set")
|
||||||
)
|
)
|
||||||
})
|
}
|
||||||
return kickMemberResponse { }
|
)
|
||||||
|
return KickMemberResponse.newBuilder().build()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Grpc("GroupService", "LeaveGroup")
|
@Grpc("GroupService", "LeaveGroup")
|
||||||
override suspend fun leaveGroup(request: LeaveGroupRequest): LeaveGroupResponse {
|
override suspend fun leaveGroup(request: LeaveGroupRequest): LeaveGroupResponse {
|
||||||
GroupHelper.resignTroop(request.groupId.toString())
|
GroupHelper.resignTroop(request.groupId.toString())
|
||||||
return leaveGroupResponse { }
|
return LeaveGroupResponse.newBuilder().build()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Grpc("GroupService", "ModifyMemberCard")
|
@Grpc("GroupService", "ModifyMemberCard")
|
||||||
override suspend fun modifyMemberCard(request: ModifyMemberCardRequest): ModifyMemberCardResponse {
|
override suspend fun modifyMemberCard(request: ModifyMemberCardRequest): ModifyMemberCardResponse {
|
||||||
if (!GroupHelper.isAdmin(request.groupId.toString())) {
|
if (!GroupHelper.isAdmin(request.groupId.toString())) {
|
||||||
throw StatusRuntimeException(Status.PERMISSION_DENIED
|
throw StatusRuntimeException(
|
||||||
|
Status.PERMISSION_DENIED
|
||||||
.withDescription("You are not admin of this group")
|
.withDescription("You are not admin of this group")
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
GroupHelper.modifyGroupMemberCard(request.groupId, when(request.targetCase!!) {
|
GroupHelper.modifyGroupMemberCard(
|
||||||
|
request.groupId, when (request.targetCase!!) {
|
||||||
ModifyMemberCardRequest.TargetCase.TARGET_UIN -> request.targetUin
|
ModifyMemberCardRequest.TargetCase.TARGET_UIN -> request.targetUin
|
||||||
ModifyMemberCardRequest.TargetCase.TARGET_UID -> ContactHelper.getUinByUidAsync(request.targetUid).toLong()
|
ModifyMemberCardRequest.TargetCase.TARGET_UID -> ContactHelper.getUinByUidAsync(request.targetUid)
|
||||||
else -> throw StatusRuntimeException(Status.INVALID_ARGUMENT
|
.toLong()
|
||||||
|
|
||||||
|
else -> throw StatusRuntimeException(
|
||||||
|
Status.INVALID_ARGUMENT
|
||||||
.withDescription("target not set")
|
.withDescription("target not set")
|
||||||
)
|
)
|
||||||
}, request.card)
|
}, request.card
|
||||||
return modifyMemberCardResponse { }
|
)
|
||||||
|
return ModifyMemberCardResponse.newBuilder().build()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Grpc("GroupService", "ModifyGroupName")
|
@Grpc("GroupService", "ModifyGroupName")
|
||||||
override suspend fun modifyGroupName(request: ModifyGroupNameRequest): ModifyGroupNameResponse {
|
override suspend fun modifyGroupName(request: ModifyGroupNameRequest): ModifyGroupNameResponse {
|
||||||
if (!GroupHelper.isAdmin(request.groupId.toString())) {
|
if (!GroupHelper.isAdmin(request.groupId.toString())) {
|
||||||
throw StatusRuntimeException(Status.PERMISSION_DENIED
|
throw StatusRuntimeException(
|
||||||
|
Status.PERMISSION_DENIED
|
||||||
.withDescription("You are not admin of this group")
|
.withDescription("You are not admin of this group")
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
GroupHelper.modifyTroopName(request.groupId.toString(), request.groupName)
|
GroupHelper.modifyTroopName(request.groupId.toString(), request.groupName)
|
||||||
|
|
||||||
return modifyGroupNameResponse { }
|
return ModifyGroupNameResponse.newBuilder().build()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Grpc("GroupService", "ModifyGroupRemark")
|
@Grpc("GroupService", "ModifyGroupRemark")
|
||||||
override suspend fun modifyGroupRemark(request: ModifyGroupRemarkRequest): ModifyGroupRemarkResponse {
|
override suspend fun modifyGroupRemark(request: ModifyGroupRemarkRequest): ModifyGroupRemarkResponse {
|
||||||
GroupHelper.modifyGroupRemark(request.groupId, request.remark)
|
GroupHelper.modifyGroupRemark(request.groupId, request.remark)
|
||||||
|
|
||||||
return modifyGroupRemarkResponse { }
|
return ModifyGroupRemarkResponse.newBuilder().build()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Grpc("GroupService", "SetGroupAdmin")
|
@Grpc("GroupService", "SetGroupAdmin")
|
||||||
override suspend fun setGroupAdmin(request: SetGroupAdminRequest): SetGroupAdminResponse {
|
override suspend fun setGroupAdmin(request: SetGroupAdminRequest): SetGroupAdminResponse {
|
||||||
if (!GroupHelper.isOwner(request.groupId.toString())) {
|
if (!GroupHelper.isOwner(request.groupId.toString())) {
|
||||||
throw StatusRuntimeException(Status.PERMISSION_DENIED
|
throw StatusRuntimeException(
|
||||||
|
Status.PERMISSION_DENIED
|
||||||
.withDescription("You are not admin of this group")
|
.withDescription("You are not admin of this group")
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
GroupHelper.setGroupAdmin(request.groupId, when(request.targetCase!!) {
|
GroupHelper.setGroupAdmin(
|
||||||
|
request.groupId, when (request.targetCase!!) {
|
||||||
SetGroupAdminRequest.TargetCase.TARGET_UIN -> request.targetUin
|
SetGroupAdminRequest.TargetCase.TARGET_UIN -> request.targetUin
|
||||||
SetGroupAdminRequest.TargetCase.TARGET_UID -> ContactHelper.getUinByUidAsync(request.targetUid).toLong()
|
SetGroupAdminRequest.TargetCase.TARGET_UID -> ContactHelper.getUinByUidAsync(request.targetUid).toLong()
|
||||||
else -> throw StatusRuntimeException(Status.INVALID_ARGUMENT
|
else -> throw StatusRuntimeException(
|
||||||
|
Status.INVALID_ARGUMENT
|
||||||
.withDescription("target not set")
|
.withDescription("target not set")
|
||||||
)
|
)
|
||||||
}, request.isAdmin)
|
}, request.isAdmin
|
||||||
|
)
|
||||||
|
|
||||||
return setGroupAdminResponse { }
|
return SetGroupAdminResponse.newBuilder().build()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Grpc("GroupService", "SetGroupUniqueTitle")
|
@Grpc("GroupService", "SetGroupUniqueTitle")
|
||||||
override suspend fun setGroupUniqueTitle(request: SetGroupUniqueTitleRequest): SetGroupUniqueTitleResponse {
|
override suspend fun setGroupUniqueTitle(request: SetGroupUniqueTitleRequest): SetGroupUniqueTitleResponse {
|
||||||
if (!GroupHelper.isAdmin(request.groupId.toString())) {
|
if (!GroupHelper.isAdmin(request.groupId.toString())) {
|
||||||
throw StatusRuntimeException(Status.PERMISSION_DENIED
|
throw StatusRuntimeException(
|
||||||
|
Status.PERMISSION_DENIED
|
||||||
.withDescription("You are not admin of this group")
|
.withDescription("You are not admin of this group")
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
GroupHelper.setGroupUniqueTitle(request.groupId.toString(), when(request.targetCase!!) {
|
GroupHelper.setGroupUniqueTitle(
|
||||||
|
request.groupId.toString(), when (request.targetCase!!) {
|
||||||
SetGroupUniqueTitleRequest.TargetCase.TARGET_UIN -> request.targetUin
|
SetGroupUniqueTitleRequest.TargetCase.TARGET_UIN -> request.targetUin
|
||||||
SetGroupUniqueTitleRequest.TargetCase.TARGET_UID -> ContactHelper.getUinByUidAsync(request.targetUid).toLong()
|
SetGroupUniqueTitleRequest.TargetCase.TARGET_UID -> ContactHelper.getUinByUidAsync(request.targetUid)
|
||||||
else -> throw StatusRuntimeException(Status.INVALID_ARGUMENT
|
.toLong()
|
||||||
|
|
||||||
|
else -> throw StatusRuntimeException(
|
||||||
|
Status.INVALID_ARGUMENT
|
||||||
.withDescription("target not set")
|
.withDescription("target not set")
|
||||||
)
|
)
|
||||||
}.toString(), request.uniqueTitle)
|
}.toString(), request.uniqueTitle
|
||||||
|
)
|
||||||
|
|
||||||
return setGroupUniqueTitleResponse { }
|
return SetGroupUniqueTitleResponse.newBuilder().build()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Grpc("GroupService", "SetGroupWholeBan")
|
@Grpc("GroupService", "SetGroupWholeBan")
|
||||||
override suspend fun setGroupWholeBan(request: SetGroupWholeBanRequest): SetGroupWholeBanResponse {
|
override suspend fun setGroupWholeBan(request: SetGroupWholeBanRequest): SetGroupWholeBanResponse {
|
||||||
if (!GroupHelper.isAdmin(request.groupId.toString())) {
|
if (!GroupHelper.isAdmin(request.groupId.toString())) {
|
||||||
throw StatusRuntimeException(Status.PERMISSION_DENIED
|
throw StatusRuntimeException(
|
||||||
|
Status.PERMISSION_DENIED
|
||||||
.withDescription("You are not admin of this group")
|
.withDescription("You are not admin of this group")
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
GroupHelper.setGroupWholeBan(request.groupId, request.isBan)
|
GroupHelper.setGroupWholeBan(request.groupId, request.isBan)
|
||||||
return setGroupWholeBanResponse { }
|
return SetGroupWholeBanResponse.newBuilder().build()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Grpc("GroupService", "GetGroupInfo")
|
@Grpc("GroupService", "GetGroupInfo")
|
||||||
@ -215,18 +189,20 @@ internal object GroupService: GroupServiceGrpcKt.GroupServiceCoroutineImplBase()
|
|||||||
val groupInfo = GroupHelper.getGroupInfo(request.groupId.toString(), true).onFailure {
|
val groupInfo = GroupHelper.getGroupInfo(request.groupId.toString(), true).onFailure {
|
||||||
throw StatusRuntimeException(Status.INTERNAL.withDescription("unable to get group info").withCause(it))
|
throw StatusRuntimeException(Status.INTERNAL.withDescription("unable to get group info").withCause(it))
|
||||||
}.getOrThrow()
|
}.getOrThrow()
|
||||||
return getGroupInfoResponse {
|
return GetGroupInfoResponse.newBuilder().apply {
|
||||||
this.groupInfo = io.kritor.group.groupInfo {
|
this.groupInfo = GroupInfo.newBuilder().apply {
|
||||||
groupId = groupInfo.troopcode.toLong()
|
groupId = groupInfo.troopcode.toLong()
|
||||||
groupName = groupInfo.troopname.ifNullOrEmpty { groupInfo.troopRemark }.ifNullOrEmpty { groupInfo.newTroopName } ?: ""
|
groupName =
|
||||||
|
groupInfo.troopname.ifNullOrEmpty { groupInfo.troopRemark }.ifNullOrEmpty { groupInfo.newTroopName }
|
||||||
|
?: ""
|
||||||
groupRemark = groupInfo.troopRemark ?: ""
|
groupRemark = groupInfo.troopRemark ?: ""
|
||||||
owner = groupInfo.troopowneruin?.toLong() ?: 0
|
owner = groupInfo.troopowneruin?.toLong() ?: 0
|
||||||
admins.addAll(GroupHelper.getAdminList(groupId))
|
addAllAdmins(GroupHelper.getAdminList(groupId))
|
||||||
maxMemberCount = groupInfo.wMemberMax
|
maxMemberCount = groupInfo.wMemberMax
|
||||||
memberCount = groupInfo.wMemberNum
|
memberCount = groupInfo.wMemberNum
|
||||||
groupUin = groupInfo.troopuin?.toLong() ?: 0
|
groupUin = groupInfo.troopuin?.toLong() ?: 0
|
||||||
}
|
}.build()
|
||||||
}
|
}.build()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Grpc("GroupService", "GetGroupList")
|
@Grpc("GroupService", "GetGroupList")
|
||||||
@ -234,36 +210,45 @@ internal object GroupService: GroupServiceGrpcKt.GroupServiceCoroutineImplBase()
|
|||||||
val groupList = GroupHelper.getGroupList(if (request.hasRefresh()) request.refresh else false).onFailure {
|
val groupList = GroupHelper.getGroupList(if (request.hasRefresh()) request.refresh else false).onFailure {
|
||||||
throw StatusRuntimeException(Status.INTERNAL.withDescription("unable to get group list").withCause(it))
|
throw StatusRuntimeException(Status.INTERNAL.withDescription("unable to get group list").withCause(it))
|
||||||
}.getOrThrow()
|
}.getOrThrow()
|
||||||
return getGroupListResponse {
|
return GetGroupListResponse.newBuilder().apply {
|
||||||
groupList.forEach { groupInfo ->
|
groupList.forEach { groupInfo ->
|
||||||
this.groupInfo.add(io.kritor.group.groupInfo {
|
this.addGroupInfo(GroupInfo.newBuilder().apply {
|
||||||
groupId = groupInfo.troopcode.toLong()
|
groupId = groupInfo.troopcode.toLong()
|
||||||
groupName = groupInfo.troopname.ifNullOrEmpty { groupInfo.troopRemark }.ifNullOrEmpty { groupInfo.newTroopName } ?: ""
|
groupName = groupInfo.troopname.ifNullOrEmpty { groupInfo.troopRemark }
|
||||||
|
.ifNullOrEmpty { groupInfo.newTroopName } ?: ""
|
||||||
groupRemark = groupInfo.troopRemark ?: ""
|
groupRemark = groupInfo.troopRemark ?: ""
|
||||||
owner = groupInfo.troopowneruin?.toLong() ?: 0
|
owner = groupInfo.troopowneruin?.toLong() ?: 0
|
||||||
admins.addAll(GroupHelper.getAdminList(groupId))
|
addAllAdmins(GroupHelper.getAdminList(groupId))
|
||||||
maxMemberCount = groupInfo.wMemberMax
|
maxMemberCount = groupInfo.wMemberMax
|
||||||
memberCount = groupInfo.wMemberNum
|
memberCount = groupInfo.wMemberNum
|
||||||
groupUin = groupInfo.troopuin?.toLong() ?: 0
|
groupUin = groupInfo.troopuin?.toLong() ?: 0
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}.build()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Grpc("GroupService", "GetGroupMemberInfo")
|
@Grpc("GroupService", "GetGroupMemberInfo")
|
||||||
override suspend fun getGroupMemberInfo(request: GetGroupMemberInfoRequest): GetGroupMemberInfoResponse {
|
override suspend fun getGroupMemberInfo(request: GetGroupMemberInfoRequest): GetGroupMemberInfoResponse {
|
||||||
val memberInfo = GroupHelper.getTroopMemberInfoByUin(request.groupId.toString(), when(request.targetCase!!) {
|
val memberInfo = GroupHelper.getTroopMemberInfoByUin(
|
||||||
|
request.groupId.toString(), when (request.targetCase!!) {
|
||||||
GetGroupMemberInfoRequest.TargetCase.UIN -> request.uin
|
GetGroupMemberInfoRequest.TargetCase.UIN -> request.uin
|
||||||
GetGroupMemberInfoRequest.TargetCase.UID -> ContactHelper.getUinByUidAsync(request.uid).toLong()
|
GetGroupMemberInfoRequest.TargetCase.UID -> ContactHelper.getUinByUidAsync(request.uid).toLong()
|
||||||
else -> throw StatusRuntimeException(Status.INVALID_ARGUMENT
|
else -> throw StatusRuntimeException(
|
||||||
|
Status.INVALID_ARGUMENT
|
||||||
.withDescription("target not set")
|
.withDescription("target not set")
|
||||||
)
|
)
|
||||||
}.toString()).onFailure {
|
}.toString()
|
||||||
throw StatusRuntimeException(Status.INTERNAL.withDescription("unable to get group member info").withCause(it))
|
).onFailure {
|
||||||
|
throw StatusRuntimeException(
|
||||||
|
Status.INTERNAL.withDescription("unable to get group member info").withCause(it)
|
||||||
|
)
|
||||||
}.getOrThrow()
|
}.getOrThrow()
|
||||||
return getGroupMemberInfoResponse {
|
return GetGroupMemberInfoResponse.newBuilder().apply {
|
||||||
groupMemberInfo = groupMemberInfo {
|
groupMemberInfo = GroupMemberInfo.newBuilder().apply {
|
||||||
uid = if (request.targetCase == GetGroupMemberInfoRequest.TargetCase.UID) request.uid else ContactHelper.getUidByUinAsync(request.uin)
|
uid =
|
||||||
|
if (request.targetCase == GetGroupMemberInfoRequest.TargetCase.UID) request.uid else ContactHelper.getUidByUinAsync(
|
||||||
|
request.uin
|
||||||
|
)
|
||||||
uin = memberInfo.memberuin?.toLong() ?: 0
|
uin = memberInfo.memberuin?.toLong() ?: 0
|
||||||
nick = memberInfo.troopnick
|
nick = memberInfo.troopnick
|
||||||
.ifNullOrEmpty { memberInfo.hwName }
|
.ifNullOrEmpty { memberInfo.hwName }
|
||||||
@ -279,24 +264,29 @@ internal object GroupService: GroupServiceGrpcKt.GroupServiceCoroutineImplBase()
|
|||||||
shutUpTimestamp = memberInfo.gagTimeStamp
|
shutUpTimestamp = memberInfo.gagTimeStamp
|
||||||
|
|
||||||
distance = memberInfo.distance
|
distance = memberInfo.distance
|
||||||
honor.addAll((memberInfo.honorList ?: "")
|
addAllHonor((memberInfo.honorList ?: "")
|
||||||
.split("|")
|
.split("|")
|
||||||
.filter { it.isNotBlank() }
|
.filter { it.isNotBlank() }
|
||||||
.map { it.toInt() })
|
.map { it.toInt() })
|
||||||
unfriendly = false
|
unfriendly = false
|
||||||
cardChangeable = GroupHelper.isAdmin(request.groupId.toString())
|
cardChangeable = GroupHelper.isAdmin(request.groupId.toString())
|
||||||
}
|
}.build()
|
||||||
}
|
}.build()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Grpc("GroupService", "GetGroupMemberList")
|
@Grpc("GroupService", "GetGroupMemberList")
|
||||||
override suspend fun getGroupMemberList(request: GetGroupMemberListRequest): GetGroupMemberListResponse {
|
override suspend fun getGroupMemberList(request: GetGroupMemberListRequest): GetGroupMemberListResponse {
|
||||||
val memberList = GroupHelper.getGroupMemberList(request.groupId.toString(), if (request.hasRefresh()) request.refresh else false).onFailure {
|
val memberList = GroupHelper.getGroupMemberList(
|
||||||
throw StatusRuntimeException(Status.INTERNAL.withDescription("unable to get group member list").withCause(it))
|
request.groupId.toString(),
|
||||||
|
if (request.hasRefresh()) request.refresh else false
|
||||||
|
).onFailure {
|
||||||
|
throw StatusRuntimeException(
|
||||||
|
Status.INTERNAL.withDescription("unable to get group member list").withCause(it)
|
||||||
|
)
|
||||||
}.getOrThrow()
|
}.getOrThrow()
|
||||||
return getGroupMemberListResponse {
|
return GetGroupMemberListResponse.newBuilder().apply {
|
||||||
memberList.forEach { memberInfo ->
|
memberList.forEach { memberInfo ->
|
||||||
this.groupMemberInfo.add(groupMemberInfo {
|
this.addGroupMemberInfo(GroupMemberInfo.newBuilder().apply {
|
||||||
uid = ContactHelper.getUidByUinAsync(memberInfo.memberuin?.toLong() ?: 0)
|
uid = ContactHelper.getUidByUinAsync(memberInfo.memberuin?.toLong() ?: 0)
|
||||||
uin = memberInfo.memberuin?.toLong() ?: 0
|
uin = memberInfo.memberuin?.toLong() ?: 0
|
||||||
nick = memberInfo.troopnick
|
nick = memberInfo.troopnick
|
||||||
@ -313,7 +303,7 @@ internal object GroupService: GroupServiceGrpcKt.GroupServiceCoroutineImplBase()
|
|||||||
shutUpTimestamp = memberInfo.gagTimeStamp
|
shutUpTimestamp = memberInfo.gagTimeStamp
|
||||||
|
|
||||||
distance = memberInfo.distance
|
distance = memberInfo.distance
|
||||||
honor.addAll((memberInfo.honorList ?: "")
|
addAllHonor((memberInfo.honorList ?: "")
|
||||||
.split("|")
|
.split("|")
|
||||||
.filter { it.isNotBlank() }
|
.filter { it.isNotBlank() }
|
||||||
.map { it.toInt() })
|
.map { it.toInt() })
|
||||||
@ -321,23 +311,25 @@ internal object GroupService: GroupServiceGrpcKt.GroupServiceCoroutineImplBase()
|
|||||||
cardChangeable = GroupHelper.isAdmin(request.groupId.toString())
|
cardChangeable = GroupHelper.isAdmin(request.groupId.toString())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}.build()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Grpc("GroupService", "GetProhibitedUserList")
|
@Grpc("GroupService", "GetProhibitedUserList")
|
||||||
override suspend fun getProhibitedUserList(request: GetProhibitedUserListRequest): GetProhibitedUserListResponse {
|
override suspend fun getProhibitedUserList(request: GetProhibitedUserListRequest): GetProhibitedUserListResponse {
|
||||||
val prohibitedList = GroupHelper.getProhibitedMemberList(request.groupId).onFailure {
|
val prohibitedList = GroupHelper.getProhibitedMemberList(request.groupId).onFailure {
|
||||||
throw StatusRuntimeException(Status.INTERNAL.withDescription("unable to get prohibited user list").withCause(it))
|
throw StatusRuntimeException(
|
||||||
|
Status.INTERNAL.withDescription("unable to get prohibited user list").withCause(it)
|
||||||
|
)
|
||||||
}.getOrThrow()
|
}.getOrThrow()
|
||||||
return getProhibitedUserListResponse {
|
return GetProhibitedUserListResponse.newBuilder().apply {
|
||||||
prohibitedList.forEach {
|
prohibitedList.forEach {
|
||||||
this.prohibitedUserInfo.add(prohibitedUserInfo {
|
this.addProhibitedUserInfo(ProhibitedUserInfo.newBuilder().apply {
|
||||||
uid = ContactHelper.getUidByUinAsync(it.memberUin)
|
uid = ContactHelper.getUidByUinAsync(it.memberUin)
|
||||||
uin = it.memberUin
|
uin = it.memberUin
|
||||||
prohibitedTime = it.shutuptimestap
|
prohibitedTime = it.shutuptimestap
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}.build()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Grpc("GroupService", "GetRemainCountAtAll")
|
@Grpc("GroupService", "GetRemainCountAtAll")
|
||||||
@ -345,20 +337,22 @@ internal object GroupService: GroupServiceGrpcKt.GroupServiceCoroutineImplBase()
|
|||||||
val remainAtAllRsp = GroupHelper.getGroupRemainAtAllRemain(request.groupId).onFailure {
|
val remainAtAllRsp = GroupHelper.getGroupRemainAtAllRemain(request.groupId).onFailure {
|
||||||
throw StatusRuntimeException(Status.INTERNAL.withDescription("unable to get remain count").withCause(it))
|
throw StatusRuntimeException(Status.INTERNAL.withDescription("unable to get remain count").withCause(it))
|
||||||
}.getOrThrow()
|
}.getOrThrow()
|
||||||
return getRemainCountAtAllResponse {
|
return GetRemainCountAtAllResponse.newBuilder().apply {
|
||||||
accessAtAll = remainAtAllRsp.bool_can_at_all.get()
|
accessAtAll = remainAtAllRsp.bool_can_at_all.get()
|
||||||
remainCountForGroup = remainAtAllRsp.uint32_remain_at_all_count_for_group.get()
|
remainCountForGroup = remainAtAllRsp.uint32_remain_at_all_count_for_group.get()
|
||||||
remainCountForSelf = remainAtAllRsp.uint32_remain_at_all_count_for_uin.get()
|
remainCountForSelf = remainAtAllRsp.uint32_remain_at_all_count_for_uin.get()
|
||||||
}
|
}.build()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Grpc("GroupService", "GetNotJoinedGroupInfo")
|
@Grpc("GroupService", "GetNotJoinedGroupInfo")
|
||||||
override suspend fun getNotJoinedGroupInfo(request: GetNotJoinedGroupInfoRequest): GetNotJoinedGroupInfoResponse {
|
override suspend fun getNotJoinedGroupInfo(request: GetNotJoinedGroupInfoRequest): GetNotJoinedGroupInfoResponse {
|
||||||
val groupInfo = GroupHelper.getNotJoinedGroupInfo(request.groupId).onFailure {
|
val groupInfo = GroupHelper.getNotJoinedGroupInfo(request.groupId).onFailure {
|
||||||
throw StatusRuntimeException(Status.INTERNAL.withDescription("unable to get not joined group info").withCause(it))
|
throw StatusRuntimeException(
|
||||||
|
Status.INTERNAL.withDescription("unable to get not joined group info").withCause(it)
|
||||||
|
)
|
||||||
}.getOrThrow()
|
}.getOrThrow()
|
||||||
return getNotJoinedGroupInfoResponse {
|
return GetNotJoinedGroupInfoResponse.newBuilder().apply {
|
||||||
this.groupInfo = notJoinedGroupInfo {
|
this.groupInfo = NotJoinedGroupInfo.newBuilder().apply {
|
||||||
groupId = groupInfo.groupId
|
groupId = groupInfo.groupId
|
||||||
groupName = groupInfo.groupName
|
groupName = groupInfo.groupName
|
||||||
owner = groupInfo.owner
|
owner = groupInfo.owner
|
||||||
@ -368,15 +362,17 @@ internal object GroupService: GroupServiceGrpcKt.GroupServiceCoroutineImplBase()
|
|||||||
createTime = groupInfo.createTime.toInt()
|
createTime = groupInfo.createTime.toInt()
|
||||||
groupFlag = groupInfo.groupFlag
|
groupFlag = groupInfo.groupFlag
|
||||||
groupFlagExt = groupInfo.groupFlagExt
|
groupFlagExt = groupInfo.groupFlagExt
|
||||||
}
|
}.build()
|
||||||
}
|
}.build()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Grpc("GroupService", "GetGroupHonor")
|
@Grpc("GroupService", "GetGroupHonor")
|
||||||
override suspend fun getGroupHonor(request: GetGroupHonorRequest): GetGroupHonorResponse {
|
override suspend fun getGroupHonor(request: GetGroupHonorRequest): GetGroupHonorResponse {
|
||||||
return getGroupHonorResponse {
|
return GetGroupHonorResponse.newBuilder().apply {
|
||||||
GroupHelper.getGroupMemberList(request.groupId.toString(), true).onFailure {
|
GroupHelper.getGroupMemberList(request.groupId.toString(), true).onFailure {
|
||||||
throw StatusRuntimeException(Status.INTERNAL.withDescription("unable to get group member list").withCause(it))
|
throw StatusRuntimeException(
|
||||||
|
Status.INTERNAL.withDescription("unable to get group member list").withCause(it)
|
||||||
|
)
|
||||||
}.onSuccess { memberList ->
|
}.onSuccess { memberList ->
|
||||||
memberList.forEach { member ->
|
memberList.forEach { member ->
|
||||||
(member.honorList ?: "").split("|")
|
(member.honorList ?: "").split("|")
|
||||||
@ -384,7 +380,7 @@ internal object GroupService: GroupServiceGrpcKt.GroupServiceCoroutineImplBase()
|
|||||||
.map { it.toInt() }.forEach {
|
.map { it.toInt() }.forEach {
|
||||||
val honor = decodeHonor(member.memberuin.toLong(), it, member.mHonorRichFlag)
|
val honor = decodeHonor(member.memberuin.toLong(), it, member.mHonorRichFlag)
|
||||||
if (honor != null) {
|
if (honor != null) {
|
||||||
groupHonorInfo.add(groupHonorInfo {
|
addGroupHonorInfo(GroupHonorInfo.newBuilder().apply {
|
||||||
uid = ContactHelper.getUidByUinAsync(member.memberuin.toLong())
|
uid = ContactHelper.getUidByUinAsync(member.memberuin.toLong())
|
||||||
uin = member.memberuin.toLong()
|
uin = member.memberuin.toLong()
|
||||||
nick = member.troopnick
|
nick = member.troopnick
|
||||||
@ -400,6 +396,6 @@ internal object GroupService: GroupServiceGrpcKt.GroupServiceCoroutineImplBase()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}.build()
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -4,25 +4,7 @@ import android.util.Base64
|
|||||||
import com.tencent.mobileqq.app.QQAppInterface
|
import com.tencent.mobileqq.app.QQAppInterface
|
||||||
import io.grpc.Status
|
import io.grpc.Status
|
||||||
import io.grpc.StatusRuntimeException
|
import io.grpc.StatusRuntimeException
|
||||||
import io.kritor.core.ClearCacheRequest
|
import io.kritor.core.*
|
||||||
import io.kritor.core.ClearCacheResponse
|
|
||||||
import io.kritor.core.DownloadFileRequest
|
|
||||||
import io.kritor.core.DownloadFileResponse
|
|
||||||
import io.kritor.core.GetCurrentAccountRequest
|
|
||||||
import io.kritor.core.GetCurrentAccountResponse
|
|
||||||
import io.kritor.core.GetDeviceBatteryRequest
|
|
||||||
import io.kritor.core.GetDeviceBatteryResponse
|
|
||||||
import io.kritor.core.GetVersionRequest
|
|
||||||
import io.kritor.core.GetVersionResponse
|
|
||||||
import io.kritor.core.KritorServiceGrpcKt
|
|
||||||
import io.kritor.core.SwitchAccountRequest
|
|
||||||
import io.kritor.core.SwitchAccountResponse
|
|
||||||
import io.kritor.core.clearCacheResponse
|
|
||||||
import io.kritor.core.downloadFileResponse
|
|
||||||
import io.kritor.core.getCurrentAccountResponse
|
|
||||||
import io.kritor.core.getDeviceBatteryResponse
|
|
||||||
import io.kritor.core.getVersionResponse
|
|
||||||
import io.kritor.core.switchAccountResponse
|
|
||||||
import moe.fuqiuluo.shamrock.tools.ShamrockVersion
|
import moe.fuqiuluo.shamrock.tools.ShamrockVersion
|
||||||
import moe.fuqiuluo.shamrock.utils.DownloadUtils
|
import moe.fuqiuluo.shamrock.utils.DownloadUtils
|
||||||
import moe.fuqiuluo.shamrock.utils.FileUtils
|
import moe.fuqiuluo.shamrock.utils.FileUtils
|
||||||
@ -30,7 +12,6 @@ import moe.fuqiuluo.shamrock.utils.MD5
|
|||||||
import moe.fuqiuluo.shamrock.utils.MMKVFetcher
|
import moe.fuqiuluo.shamrock.utils.MMKVFetcher
|
||||||
import moe.fuqiuluo.shamrock.utils.PlatformUtils
|
import moe.fuqiuluo.shamrock.utils.PlatformUtils
|
||||||
import mqq.app.MobileQQ
|
import mqq.app.MobileQQ
|
||||||
import qq.service.QQInterfaces
|
|
||||||
import qq.service.QQInterfaces.Companion.app
|
import qq.service.QQInterfaces.Companion.app
|
||||||
import qq.service.contact.ContactHelper
|
import qq.service.contact.ContactHelper
|
||||||
import java.io.File
|
import java.io.File
|
||||||
@ -38,10 +19,10 @@ import java.io.File
|
|||||||
internal object KritorService : KritorServiceGrpcKt.KritorServiceCoroutineImplBase() {
|
internal object KritorService : KritorServiceGrpcKt.KritorServiceCoroutineImplBase() {
|
||||||
@Grpc("KritorService", "GetVersion")
|
@Grpc("KritorService", "GetVersion")
|
||||||
override suspend fun getVersion(request: GetVersionRequest): GetVersionResponse {
|
override suspend fun getVersion(request: GetVersionRequest): GetVersionResponse {
|
||||||
return getVersionResponse {
|
return GetVersionResponse.newBuilder().apply {
|
||||||
this.version = ShamrockVersion
|
this.version = ShamrockVersion
|
||||||
this.appName = "Shamrock"
|
this.appName = "Shamrock"
|
||||||
}
|
}.build()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Grpc("KritorService", "ClearCache")
|
@Grpc("KritorService", "ClearCache")
|
||||||
@ -49,16 +30,16 @@ internal object KritorService: KritorServiceGrpcKt.KritorServiceCoroutineImplBas
|
|||||||
FileUtils.clearCache()
|
FileUtils.clearCache()
|
||||||
MMKVFetcher.mmkvWithId("audio2silk")
|
MMKVFetcher.mmkvWithId("audio2silk")
|
||||||
.clear()
|
.clear()
|
||||||
return clearCacheResponse {}
|
return ClearCacheResponse.newBuilder().build()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Grpc("KritorService", "GetCurrentAccount")
|
@Grpc("KritorService", "GetCurrentAccount")
|
||||||
override suspend fun getCurrentAccount(request: GetCurrentAccountRequest): GetCurrentAccountResponse {
|
override suspend fun getCurrentAccount(request: GetCurrentAccountRequest): GetCurrentAccountResponse {
|
||||||
return getCurrentAccountResponse {
|
return GetCurrentAccountResponse.newBuilder().apply {
|
||||||
this.accountName = if (app is QQAppInterface) app.currentNickname else "unknown"
|
this.accountName = if (app is QQAppInterface) app.currentNickname else "unknown"
|
||||||
this.accountUid = app.currentUid ?: ""
|
this.accountUid = app.currentUid ?: ""
|
||||||
this.accountUin = (app.currentUin ?: "0").toLong()
|
this.accountUin = (app.currentUin ?: "0").toLong()
|
||||||
}
|
}.build()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Grpc("KritorService", "DownloadFile")
|
@Grpc("KritorService", "DownloadFile")
|
||||||
@ -86,7 +67,8 @@ internal object KritorService: KritorServiceGrpcKt.KritorServiceCoroutineImplBas
|
|||||||
dest = tmp,
|
dest = tmp,
|
||||||
headers = headerMap,
|
headers = headerMap,
|
||||||
threadCount = if (request.hasThreadCnt()) request.threadCnt else 3
|
threadCount = if (request.hasThreadCnt()) request.threadCnt else 3
|
||||||
)) {
|
)
|
||||||
|
) {
|
||||||
throw StatusRuntimeException(Status.INTERNAL.withDescription("download failed"))
|
throw StatusRuntimeException(Status.INTERNAL.withDescription("download failed"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -100,10 +82,10 @@ internal object KritorService: KritorServiceGrpcKt.KritorServiceCoroutineImplBas
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return downloadFileResponse {
|
return DownloadFileResponse.newBuilder().apply {
|
||||||
this.fileMd5 = MD5.genFileMd5Hex(tmp.absolutePath)
|
this.fileMd5 = MD5.genFileMd5Hex(tmp.absolutePath)
|
||||||
this.fileAbsolutePath = tmp.absolutePath
|
this.fileAbsolutePath = tmp.absolutePath
|
||||||
}
|
}.build()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Grpc("KritorService", "SwitchAccount")
|
@Grpc("KritorService", "SwitchAccount")
|
||||||
@ -111,7 +93,11 @@ internal object KritorService: KritorServiceGrpcKt.KritorServiceCoroutineImplBas
|
|||||||
val uin = when (request.accountCase!!) {
|
val uin = when (request.accountCase!!) {
|
||||||
SwitchAccountRequest.AccountCase.ACCOUNT_UID -> ContactHelper.getUinByUidAsync(request.accountUid)
|
SwitchAccountRequest.AccountCase.ACCOUNT_UID -> ContactHelper.getUinByUidAsync(request.accountUid)
|
||||||
SwitchAccountRequest.AccountCase.ACCOUNT_UIN -> request.accountUin.toString()
|
SwitchAccountRequest.AccountCase.ACCOUNT_UIN -> request.accountUin.toString()
|
||||||
SwitchAccountRequest.AccountCase.ACCOUNT_NOT_SET -> throw StatusRuntimeException(Status.INVALID_ARGUMENT.withDescription("account not found"))
|
SwitchAccountRequest.AccountCase.ACCOUNT_NOT_SET -> throw StatusRuntimeException(
|
||||||
|
Status.INVALID_ARGUMENT.withDescription(
|
||||||
|
"account not found"
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
val account = MobileQQ.getMobileQQ().allAccounts.firstOrNull { it.uin == uin }
|
val account = MobileQQ.getMobileQQ().allAccounts.firstOrNull { it.uin == uin }
|
||||||
?: throw StatusRuntimeException(Status.NOT_FOUND.withDescription("account not found"))
|
?: throw StatusRuntimeException(Status.NOT_FOUND.withDescription("account not found"))
|
||||||
@ -120,17 +106,17 @@ internal object KritorService: KritorServiceGrpcKt.KritorServiceCoroutineImplBas
|
|||||||
}.onFailure {
|
}.onFailure {
|
||||||
throw StatusRuntimeException(Status.INTERNAL.withCause(it).withDescription("failed to switch account"))
|
throw StatusRuntimeException(Status.INTERNAL.withCause(it).withDescription("failed to switch account"))
|
||||||
}
|
}
|
||||||
return switchAccountResponse { }
|
return SwitchAccountResponse.newBuilder().build()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Grpc("KritorService", "GetDeviceBattery")
|
@Grpc("KritorService", "GetDeviceBattery")
|
||||||
override suspend fun getDeviceBattery(request: GetDeviceBatteryRequest): GetDeviceBatteryResponse {
|
override suspend fun getDeviceBattery(request: GetDeviceBatteryRequest): GetDeviceBatteryResponse {
|
||||||
return getDeviceBatteryResponse {
|
return GetDeviceBatteryResponse.newBuilder().apply {
|
||||||
PlatformUtils.getDeviceBattery().let {
|
PlatformUtils.getDeviceBattery().let {
|
||||||
this.battery = it.battery
|
this.battery = it.battery
|
||||||
this.scale = it.scale
|
this.scale = it.scale
|
||||||
this.status = it.status
|
this.status = it.status
|
||||||
}
|
}
|
||||||
}
|
}.build()
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -7,48 +7,8 @@ import com.tencent.qqnt.kernel.nativeinterface.MsgRecord
|
|||||||
import com.tencent.qqnt.msg.api.IMsgService
|
import com.tencent.qqnt.msg.api.IMsgService
|
||||||
import io.grpc.Status
|
import io.grpc.Status
|
||||||
import io.grpc.StatusRuntimeException
|
import io.grpc.StatusRuntimeException
|
||||||
import io.kritor.message.ClearMessagesRequest
|
import io.kritor.event.MessageEvent
|
||||||
import io.kritor.message.ClearMessagesResponse
|
import io.kritor.message.*
|
||||||
import io.kritor.message.DeleteEssenceMsgRequest
|
|
||||||
import io.kritor.message.DeleteEssenceMsgResponse
|
|
||||||
import io.kritor.message.GetEssenceMessagesRequest
|
|
||||||
import io.kritor.message.GetEssenceMessagesResponse
|
|
||||||
import io.kritor.message.GetForwardMessagesRequest
|
|
||||||
import io.kritor.message.GetForwardMessagesResponse
|
|
||||||
import io.kritor.message.GetHistoryMessageRequest
|
|
||||||
import io.kritor.message.GetHistoryMessageResponse
|
|
||||||
import io.kritor.message.GetMessageBySeqRequest
|
|
||||||
import io.kritor.message.GetMessageBySeqResponse
|
|
||||||
import io.kritor.message.GetMessageRequest
|
|
||||||
import io.kritor.message.GetMessageResponse
|
|
||||||
import io.kritor.message.MessageServiceGrpcKt
|
|
||||||
import io.kritor.message.RecallMessageRequest
|
|
||||||
import io.kritor.message.RecallMessageResponse
|
|
||||||
import io.kritor.message.Scene
|
|
||||||
import io.kritor.message.SendMessageByResIdRequest
|
|
||||||
import io.kritor.message.SendMessageByResIdResponse
|
|
||||||
import io.kritor.message.SendMessageRequest
|
|
||||||
import io.kritor.message.SendMessageResponse
|
|
||||||
import io.kritor.message.SetEssenceMessageRequest
|
|
||||||
import io.kritor.message.SetEssenceMessageResponse
|
|
||||||
import io.kritor.message.SetMessageCommentEmojiRequest
|
|
||||||
import io.kritor.message.SetMessageCommentEmojiResponse
|
|
||||||
import io.kritor.message.clearMessagesResponse
|
|
||||||
import io.kritor.message.contact
|
|
||||||
import io.kritor.message.deleteEssenceMsgResponse
|
|
||||||
import io.kritor.message.essenceMessage
|
|
||||||
import io.kritor.message.getEssenceMessagesResponse
|
|
||||||
import io.kritor.message.getForwardMessagesResponse
|
|
||||||
import io.kritor.message.getHistoryMessageResponse
|
|
||||||
import io.kritor.message.getMessageBySeqResponse
|
|
||||||
import io.kritor.message.getMessageResponse
|
|
||||||
import io.kritor.message.messageBody
|
|
||||||
import io.kritor.message.recallMessageResponse
|
|
||||||
import io.kritor.message.sendMessageByResIdResponse
|
|
||||||
import io.kritor.message.sendMessageResponse
|
|
||||||
import io.kritor.message.sender
|
|
||||||
import io.kritor.message.setEssenceMessageResponse
|
|
||||||
import io.kritor.message.setMessageCommentEmojiResponse
|
|
||||||
import kotlinx.coroutines.suspendCancellableCoroutine
|
import kotlinx.coroutines.suspendCancellableCoroutine
|
||||||
import kotlinx.coroutines.withTimeoutOrNull
|
import kotlinx.coroutines.withTimeoutOrNull
|
||||||
import moe.fuqiuluo.shamrock.helper.Level
|
import moe.fuqiuluo.shamrock.helper.Level
|
||||||
@ -79,7 +39,8 @@ internal object MessageService: MessageServiceGrpcKt.MessageServiceCoroutineImpl
|
|||||||
@Grpc("MessageService", "SendMessage")
|
@Grpc("MessageService", "SendMessage")
|
||||||
override suspend fun sendMessage(request: SendMessageRequest): SendMessageResponse {
|
override suspend fun sendMessage(request: SendMessageRequest): SendMessageResponse {
|
||||||
val contact = request.contact.let {
|
val contact = request.contact.let {
|
||||||
MessageHelper.generateContact(when(it.scene!!) {
|
MessageHelper.generateContact(
|
||||||
|
when (it.scene!!) {
|
||||||
Scene.GROUP -> MsgConstant.KCHATTYPEGROUP
|
Scene.GROUP -> MsgConstant.KCHATTYPEGROUP
|
||||||
Scene.FRIEND -> MsgConstant.KCHATTYPEC2C
|
Scene.FRIEND -> MsgConstant.KCHATTYPEC2C
|
||||||
Scene.GUILD -> MsgConstant.KCHATTYPEGUILD
|
Scene.GUILD -> MsgConstant.KCHATTYPEGUILD
|
||||||
@ -87,15 +48,21 @@ internal object MessageService: MessageServiceGrpcKt.MessageServiceCoroutineImpl
|
|||||||
Scene.NEARBY -> MsgConstant.KCHATTYPETEMPC2CFROMUNKNOWN
|
Scene.NEARBY -> MsgConstant.KCHATTYPETEMPC2CFROMUNKNOWN
|
||||||
Scene.STRANGER -> MsgConstant.KCHATTYPETEMPC2CFROMUNKNOWN
|
Scene.STRANGER -> MsgConstant.KCHATTYPETEMPC2CFROMUNKNOWN
|
||||||
Scene.UNRECOGNIZED -> throw StatusRuntimeException(Status.INVALID_ARGUMENT.withDescription("Unrecognized scene"))
|
Scene.UNRECOGNIZED -> throw StatusRuntimeException(Status.INVALID_ARGUMENT.withDescription("Unrecognized scene"))
|
||||||
}, it.peer, it.subPeer)
|
}, it.peer, it.subPeer
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
val uniseq = MessageHelper.generateMsgId(contact.chatType)
|
val uniseq = MessageHelper.generateMsgId(contact.chatType)
|
||||||
return sendMessageResponse {
|
return SendMessageResponse.newBuilder().apply {
|
||||||
this.messageId = MessageHelper.sendMessage(contact, NtMsgConvertor.convertToNtMsgs(contact, uniseq, request.elementsList), request.retryCount, uniseq).onFailure {
|
this.messageId = MessageHelper.sendMessage(
|
||||||
|
contact,
|
||||||
|
NtMsgConvertor.convertToNtMsgs(contact, uniseq, request.elementsList),
|
||||||
|
request.retryCount,
|
||||||
|
uniseq
|
||||||
|
).onFailure {
|
||||||
throw StatusRuntimeException(Status.INTERNAL.withCause(it))
|
throw StatusRuntimeException(Status.INTERNAL.withCause(it))
|
||||||
}.getOrThrow()
|
}.getOrThrow()
|
||||||
}
|
}.build()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Grpc("MessageService", "SendMessageByResId")
|
@Grpc("MessageService", "SendMessageByResId")
|
||||||
@ -125,7 +92,7 @@ internal object MessageService: MessageServiceGrpcKt.MessageServiceCoroutineImpl
|
|||||||
msgVia = 0u
|
msgVia = 0u
|
||||||
)
|
)
|
||||||
QQInterfaces.sendBuffer("MessageSvc.PbSendMsg", true, req.toByteArray())
|
QQInterfaces.sendBuffer("MessageSvc.PbSendMsg", true, req.toByteArray())
|
||||||
return sendMessageByResIdResponse { }
|
return SendMessageByResIdResponse.newBuilder().build()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Grpc("MessageService", "ClearMessages")
|
@Grpc("MessageService", "ClearMessages")
|
||||||
@ -144,13 +111,14 @@ internal object MessageService: MessageServiceGrpcKt.MessageServiceCoroutineImpl
|
|||||||
Scene.UNRECOGNIZED -> throw StatusRuntimeException(Status.INVALID_ARGUMENT.withDescription("Unrecognized scene"))
|
Scene.UNRECOGNIZED -> throw StatusRuntimeException(Status.INVALID_ARGUMENT.withDescription("Unrecognized scene"))
|
||||||
}
|
}
|
||||||
service.clearMsgRecords(Contact(chatType, contact.peer, contact.subPeer), null)
|
service.clearMsgRecords(Contact(chatType, contact.peer, contact.subPeer), null)
|
||||||
return clearMessagesResponse { }
|
return ClearMessagesResponse.newBuilder().build()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Grpc("MessageService", "RecallMessage")
|
@Grpc("MessageService", "RecallMessage")
|
||||||
override suspend fun recallMessage(request: RecallMessageRequest): RecallMessageResponse {
|
override suspend fun recallMessage(request: RecallMessageRequest): RecallMessageResponse {
|
||||||
val contact = request.contact.let {
|
val contact = request.contact.let {
|
||||||
MessageHelper.generateContact(when(it.scene!!) {
|
MessageHelper.generateContact(
|
||||||
|
when (it.scene!!) {
|
||||||
Scene.GROUP -> MsgConstant.KCHATTYPEGROUP
|
Scene.GROUP -> MsgConstant.KCHATTYPEGROUP
|
||||||
Scene.FRIEND -> MsgConstant.KCHATTYPEC2C
|
Scene.FRIEND -> MsgConstant.KCHATTYPEC2C
|
||||||
Scene.GUILD -> MsgConstant.KCHATTYPEGUILD
|
Scene.GUILD -> MsgConstant.KCHATTYPEGUILD
|
||||||
@ -158,7 +126,8 @@ internal object MessageService: MessageServiceGrpcKt.MessageServiceCoroutineImpl
|
|||||||
Scene.NEARBY -> MsgConstant.KCHATTYPETEMPC2CFROMUNKNOWN
|
Scene.NEARBY -> MsgConstant.KCHATTYPETEMPC2CFROMUNKNOWN
|
||||||
Scene.STRANGER -> MsgConstant.KCHATTYPETEMPC2CFROMUNKNOWN
|
Scene.STRANGER -> MsgConstant.KCHATTYPETEMPC2CFROMUNKNOWN
|
||||||
Scene.UNRECOGNIZED -> throw StatusRuntimeException(Status.INVALID_ARGUMENT.withDescription("Unrecognized scene"))
|
Scene.UNRECOGNIZED -> throw StatusRuntimeException(Status.INVALID_ARGUMENT.withDescription("Unrecognized scene"))
|
||||||
}, it.peer, it.subPeer)
|
}, it.peer, it.subPeer
|
||||||
|
)
|
||||||
}
|
}
|
||||||
val kernelService = NTServiceFetcher.kernelService
|
val kernelService = NTServiceFetcher.kernelService
|
||||||
val sessionService = kernelService.wrapperSession
|
val sessionService = kernelService.wrapperSession
|
||||||
@ -169,54 +138,14 @@ internal object MessageService: MessageServiceGrpcKt.MessageServiceCoroutineImpl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return recallMessageResponse {}
|
return RecallMessageResponse.newBuilder().build()
|
||||||
}
|
|
||||||
|
|
||||||
@Grpc("MessageService", "GetForwardMessages")
|
|
||||||
override suspend fun getForwardMessages(request: GetForwardMessagesRequest): GetForwardMessagesResponse {
|
|
||||||
return getForwardMessagesResponse {
|
|
||||||
MessageHelper.getForwardMsg(request.resId).onFailure {
|
|
||||||
throw StatusRuntimeException(Status.INTERNAL.withCause(it))
|
|
||||||
}.getOrThrow().forEach { detail ->
|
|
||||||
messages.add(messageBody {
|
|
||||||
val peer = when (scene) {
|
|
||||||
Scene.GROUP -> detail.groupId.toString()
|
|
||||||
Scene.FRIEND -> detail.sender.userId.toString()
|
|
||||||
else -> detail.peerId.toString()
|
|
||||||
}
|
|
||||||
|
|
||||||
this.time = detail.time
|
|
||||||
this.scene = when(detail.msgType) {
|
|
||||||
MsgConstant.KCHATTYPEC2C -> Scene.FRIEND
|
|
||||||
MsgConstant.KCHATTYPEGROUP -> Scene.GROUP
|
|
||||||
MsgConstant.KCHATTYPEGUILD -> Scene.GUILD
|
|
||||||
MsgConstant.KCHATTYPETEMPC2CFROMGROUP -> Scene.STRANGER_FROM_GROUP
|
|
||||||
MsgConstant.KCHATTYPETEMPC2CFROMUNKNOWN -> Scene.NEARBY
|
|
||||||
else -> Scene.STRANGER
|
|
||||||
}
|
|
||||||
this.messageId = detail.qqMsgId
|
|
||||||
this.messageSeq = detail.msgSeq
|
|
||||||
this.contact = contact {
|
|
||||||
this.scene = scene
|
|
||||||
this.peer = peer
|
|
||||||
}
|
|
||||||
this.sender = sender {
|
|
||||||
this.uin = detail.sender.userId
|
|
||||||
this.nick = detail.sender.nickName
|
|
||||||
this.uid = detail.sender.uid
|
|
||||||
}
|
|
||||||
detail.message?.elements?.toKritorResponseMessages(Contact(detail.msgType, peer, null))?.let {
|
|
||||||
this.elements.addAll(it)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Grpc("MessageService", "GetMessage")
|
@Grpc("MessageService", "GetMessage")
|
||||||
override suspend fun getMessage(request: GetMessageRequest): GetMessageResponse {
|
override suspend fun getMessage(request: GetMessageRequest): GetMessageResponse {
|
||||||
val contact = request.contact.let {
|
val contact = request.contact.let {
|
||||||
MessageHelper.generateContact(when(it.scene!!) {
|
MessageHelper.generateContact(
|
||||||
|
when (it.scene!!) {
|
||||||
Scene.GROUP -> MsgConstant.KCHATTYPEGROUP
|
Scene.GROUP -> MsgConstant.KCHATTYPEGROUP
|
||||||
Scene.FRIEND -> MsgConstant.KCHATTYPEC2C
|
Scene.FRIEND -> MsgConstant.KCHATTYPEC2C
|
||||||
Scene.GUILD -> MsgConstant.KCHATTYPEGUILD
|
Scene.GUILD -> MsgConstant.KCHATTYPEGUILD
|
||||||
@ -224,7 +153,8 @@ internal object MessageService: MessageServiceGrpcKt.MessageServiceCoroutineImpl
|
|||||||
Scene.NEARBY -> MsgConstant.KCHATTYPETEMPC2CFROMUNKNOWN
|
Scene.NEARBY -> MsgConstant.KCHATTYPETEMPC2CFROMUNKNOWN
|
||||||
Scene.STRANGER -> MsgConstant.KCHATTYPETEMPC2CFROMUNKNOWN
|
Scene.STRANGER -> MsgConstant.KCHATTYPETEMPC2CFROMUNKNOWN
|
||||||
Scene.UNRECOGNIZED -> throw StatusRuntimeException(Status.INVALID_ARGUMENT.withDescription("Unrecognized scene"))
|
Scene.UNRECOGNIZED -> throw StatusRuntimeException(Status.INVALID_ARGUMENT.withDescription("Unrecognized scene"))
|
||||||
}, it.peer, it.subPeer)
|
}, it.peer, it.subPeer
|
||||||
|
)
|
||||||
}
|
}
|
||||||
val msg: MsgRecord = withTimeoutOrNull(5000) {
|
val msg: MsgRecord = withTimeoutOrNull(5000) {
|
||||||
val service = QRoute.api(IMsgService::class.java)
|
val service = QRoute.api(IMsgService::class.java)
|
||||||
@ -242,26 +172,26 @@ internal object MessageService: MessageServiceGrpcKt.MessageServiceCoroutineImpl
|
|||||||
}
|
}
|
||||||
} ?: throw StatusRuntimeException(Status.NOT_FOUND.withDescription("Message not found"))
|
} ?: throw StatusRuntimeException(Status.NOT_FOUND.withDescription("Message not found"))
|
||||||
|
|
||||||
return getMessageResponse {
|
return GetMessageResponse.newBuilder().apply {
|
||||||
this.message = messageBody {
|
this.message = MessageEvent.newBuilder().apply {
|
||||||
this.messageId = msg.msgId
|
this.messageId = msg.msgId
|
||||||
this.scene = request.contact.scene
|
|
||||||
this.contact = request.contact
|
this.contact = request.contact
|
||||||
this.sender = sender {
|
this.sender = Sender.newBuilder().apply {
|
||||||
this.uin = msg.senderUin
|
this.uin = msg.senderUin
|
||||||
this.nick = msg.sendNickName ?: ""
|
this.nick = msg.sendNickName ?: ""
|
||||||
this.uid = msg.senderUid ?: ""
|
this.uid = msg.senderUid ?: ""
|
||||||
}
|
}.build()
|
||||||
this.messageSeq = msg.msgSeq
|
this.messageSeq = msg.msgSeq
|
||||||
this.elements.addAll(msg.elements.toKritorReqMessages(contact))
|
this.addAllElements(msg.elements.toKritorReqMessages(contact))
|
||||||
}
|
}.build()
|
||||||
}
|
}.build()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Grpc("MessageService", "GetMessageBySeq")
|
@Grpc("MessageService", "GetMessageBySeq")
|
||||||
override suspend fun getMessageBySeq(request: GetMessageBySeqRequest): GetMessageBySeqResponse {
|
override suspend fun getMessageBySeq(request: GetMessageBySeqRequest): GetMessageBySeqResponse {
|
||||||
val contact = request.contact.let {
|
val contact = request.contact.let {
|
||||||
MessageHelper.generateContact(when(it.scene!!) {
|
MessageHelper.generateContact(
|
||||||
|
when (it.scene!!) {
|
||||||
Scene.GROUP -> MsgConstant.KCHATTYPEGROUP
|
Scene.GROUP -> MsgConstant.KCHATTYPEGROUP
|
||||||
Scene.FRIEND -> MsgConstant.KCHATTYPEC2C
|
Scene.FRIEND -> MsgConstant.KCHATTYPEC2C
|
||||||
Scene.GUILD -> MsgConstant.KCHATTYPEGUILD
|
Scene.GUILD -> MsgConstant.KCHATTYPEGUILD
|
||||||
@ -269,7 +199,8 @@ internal object MessageService: MessageServiceGrpcKt.MessageServiceCoroutineImpl
|
|||||||
Scene.NEARBY -> MsgConstant.KCHATTYPETEMPC2CFROMUNKNOWN
|
Scene.NEARBY -> MsgConstant.KCHATTYPETEMPC2CFROMUNKNOWN
|
||||||
Scene.STRANGER -> MsgConstant.KCHATTYPETEMPC2CFROMUNKNOWN
|
Scene.STRANGER -> MsgConstant.KCHATTYPETEMPC2CFROMUNKNOWN
|
||||||
Scene.UNRECOGNIZED -> throw StatusRuntimeException(Status.INVALID_ARGUMENT.withDescription("Unrecognized scene"))
|
Scene.UNRECOGNIZED -> throw StatusRuntimeException(Status.INVALID_ARGUMENT.withDescription("Unrecognized scene"))
|
||||||
}, it.peer, it.subPeer)
|
}, it.peer, it.subPeer
|
||||||
|
)
|
||||||
}
|
}
|
||||||
val msg: MsgRecord = withTimeoutOrNull(5000) {
|
val msg: MsgRecord = withTimeoutOrNull(5000) {
|
||||||
val service = QRoute.api(IMsgService::class.java)
|
val service = QRoute.api(IMsgService::class.java)
|
||||||
@ -287,26 +218,26 @@ internal object MessageService: MessageServiceGrpcKt.MessageServiceCoroutineImpl
|
|||||||
}
|
}
|
||||||
} ?: throw StatusRuntimeException(Status.NOT_FOUND.withDescription("Message not found"))
|
} ?: throw StatusRuntimeException(Status.NOT_FOUND.withDescription("Message not found"))
|
||||||
|
|
||||||
return getMessageBySeqResponse {
|
return GetMessageBySeqResponse.newBuilder().apply {
|
||||||
this.message = messageBody {
|
this.message = MessageEvent.newBuilder().apply {
|
||||||
this.messageId = msg.msgId
|
this.messageId = msg.msgId
|
||||||
this.scene = request.contact.scene
|
|
||||||
this.contact = request.contact
|
this.contact = request.contact
|
||||||
this.sender = sender {
|
this.sender = Sender.newBuilder().apply {
|
||||||
this.uin = msg.senderUin
|
this.uin = msg.senderUin
|
||||||
this.nick = msg.sendNickName ?: ""
|
this.nick = msg.sendNickName ?: ""
|
||||||
this.uid = msg.senderUid ?: ""
|
this.uid = msg.senderUid ?: ""
|
||||||
}
|
}.build()
|
||||||
this.messageSeq = msg.msgSeq
|
this.messageSeq = msg.msgSeq
|
||||||
this.elements.addAll(msg.elements.toKritorReqMessages(contact))
|
this.addAllElements(msg.elements.toKritorReqMessages(contact))
|
||||||
}
|
}.build()
|
||||||
}
|
}.build()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Grpc("MessageService", "GetHistoryMessage")
|
@Grpc("MessageService", "GetHistoryMessage")
|
||||||
override suspend fun getHistoryMessage(request: GetHistoryMessageRequest): GetHistoryMessageResponse {
|
override suspend fun getHistoryMessage(request: GetHistoryMessageRequest): GetHistoryMessageResponse {
|
||||||
val contact = request.contact.let {
|
val contact = request.contact.let {
|
||||||
MessageHelper.generateContact(when(it.scene!!) {
|
MessageHelper.generateContact(
|
||||||
|
when (it.scene!!) {
|
||||||
Scene.GROUP -> MsgConstant.KCHATTYPEGROUP
|
Scene.GROUP -> MsgConstant.KCHATTYPEGROUP
|
||||||
Scene.FRIEND -> MsgConstant.KCHATTYPEC2C
|
Scene.FRIEND -> MsgConstant.KCHATTYPEC2C
|
||||||
Scene.GUILD -> MsgConstant.KCHATTYPEGUILD
|
Scene.GUILD -> MsgConstant.KCHATTYPEGUILD
|
||||||
@ -314,7 +245,8 @@ internal object MessageService: MessageServiceGrpcKt.MessageServiceCoroutineImpl
|
|||||||
Scene.NEARBY -> MsgConstant.KCHATTYPETEMPC2CFROMUNKNOWN
|
Scene.NEARBY -> MsgConstant.KCHATTYPETEMPC2CFROMUNKNOWN
|
||||||
Scene.STRANGER -> MsgConstant.KCHATTYPETEMPC2CFROMUNKNOWN
|
Scene.STRANGER -> MsgConstant.KCHATTYPETEMPC2CFROMUNKNOWN
|
||||||
Scene.UNRECOGNIZED -> throw StatusRuntimeException(Status.INVALID_ARGUMENT.withDescription("Unrecognized scene"))
|
Scene.UNRECOGNIZED -> throw StatusRuntimeException(Status.INVALID_ARGUMENT.withDescription("Unrecognized scene"))
|
||||||
}, it.peer, it.subPeer)
|
}, it.peer, it.subPeer
|
||||||
|
)
|
||||||
}
|
}
|
||||||
val msgs: List<MsgRecord> = withTimeoutOrNull(5000) {
|
val msgs: List<MsgRecord> = withTimeoutOrNull(5000) {
|
||||||
val service = QRoute.api(IMsgService::class.java)
|
val service = QRoute.api(IMsgService::class.java)
|
||||||
@ -332,22 +264,21 @@ internal object MessageService: MessageServiceGrpcKt.MessageServiceCoroutineImpl
|
|||||||
}
|
}
|
||||||
} ?: throw StatusRuntimeException(Status.NOT_FOUND.withDescription("Messages not found"))
|
} ?: throw StatusRuntimeException(Status.NOT_FOUND.withDescription("Messages not found"))
|
||||||
|
|
||||||
return getHistoryMessageResponse {
|
return GetHistoryMessageResponse.newBuilder().apply {
|
||||||
msgs.forEach {
|
msgs.forEach {
|
||||||
messages.add(messageBody {
|
addMessages(MessageEvent.newBuilder().apply {
|
||||||
this.messageId = it.msgId
|
this.messageId = it.msgId
|
||||||
this.scene = request.contact.scene
|
|
||||||
this.contact = request.contact
|
this.contact = request.contact
|
||||||
this.sender = sender {
|
this.sender = Sender.newBuilder().apply {
|
||||||
this.uin = it.senderUin
|
this.uin = it.senderUin
|
||||||
this.nick = it.sendNickName ?: ""
|
this.nick = it.sendNickName ?: ""
|
||||||
this.uid = it.senderUid ?: ""
|
this.uid = it.senderUid ?: ""
|
||||||
}
|
}.build()
|
||||||
this.messageSeq = it.msgSeq
|
this.messageSeq = it.msgSeq
|
||||||
this.elements.addAll(it.elements.toKritorReqMessages(contact))
|
this.addAllElements(it.elements.toKritorReqMessages(contact))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}.build()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Grpc("MessageService", "DeleteEssenceMsg")
|
@Grpc("MessageService", "DeleteEssenceMsg")
|
||||||
@ -370,17 +301,17 @@ internal object MessageService: MessageServiceGrpcKt.MessageServiceCoroutineImpl
|
|||||||
} ?: throw StatusRuntimeException(Status.NOT_FOUND.withDescription("Message not found"))
|
} ?: throw StatusRuntimeException(Status.NOT_FOUND.withDescription("Message not found"))
|
||||||
if (MessageHelper.deleteEssenceMessage(request.groupId, msg.msgSeq, msg.msgRandom) == null)
|
if (MessageHelper.deleteEssenceMessage(request.groupId, msg.msgSeq, msg.msgRandom) == null)
|
||||||
throw StatusRuntimeException(Status.NOT_FOUND.withDescription("delete essence message failed"))
|
throw StatusRuntimeException(Status.NOT_FOUND.withDescription("delete essence message failed"))
|
||||||
return deleteEssenceMsgResponse { }
|
return DeleteEssenceMsgResponse.newBuilder().build()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Grpc("MessageService", "GetEssenceMessages")
|
@Grpc("MessageService", "GetEssenceMessages")
|
||||||
override suspend fun getEssenceMessages(request: GetEssenceMessagesRequest): GetEssenceMessagesResponse {
|
override suspend fun getEssenceMessages(request: GetEssenceMessagesRequest): GetEssenceMessagesResponse {
|
||||||
val contact = MessageHelper.generateContact(MsgConstant.KCHATTYPEGROUP, request.groupId.toString())
|
val contact = MessageHelper.generateContact(MsgConstant.KCHATTYPEGROUP, request.groupId.toString())
|
||||||
return getEssenceMessagesResponse {
|
return GetEssenceMessagesResponse.newBuilder().apply {
|
||||||
MessageHelper.getEssenceMessageList(request.groupId, request.page, request.pageSize).onFailure {
|
MessageHelper.getEssenceMessageList(request.groupId, request.page, request.pageSize).onFailure {
|
||||||
throw StatusRuntimeException(Status.INTERNAL.withCause(it))
|
throw StatusRuntimeException(Status.INTERNAL.withCause(it))
|
||||||
}.getOrThrow().forEach {
|
}.getOrThrow().forEach {
|
||||||
essenceMessage.add(essenceMessage {
|
addEssenceMessage(EssenceMessage.newBuilder().apply {
|
||||||
withTimeoutOrNull(5000) {
|
withTimeoutOrNull(5000) {
|
||||||
val service = QRoute.api(IMsgService::class.java)
|
val service = QRoute.api(IMsgService::class.java)
|
||||||
suspendCancellableCoroutine { continuation ->
|
suspendCancellableCoroutine { continuation ->
|
||||||
@ -408,7 +339,7 @@ internal object MessageService: MessageServiceGrpcKt.MessageServiceCoroutineImpl
|
|||||||
this.jsonElements = it.messageContent.toString()
|
this.jsonElements = it.messageContent.toString()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}.build()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Grpc("MessageService", "SetEssenceMessage")
|
@Grpc("MessageService", "SetEssenceMessage")
|
||||||
@ -432,13 +363,14 @@ internal object MessageService: MessageServiceGrpcKt.MessageServiceCoroutineImpl
|
|||||||
if (MessageHelper.setEssenceMessage(request.groupId, msg.msgSeq, msg.msgRandom) == null) {
|
if (MessageHelper.setEssenceMessage(request.groupId, msg.msgSeq, msg.msgRandom) == null) {
|
||||||
throw StatusRuntimeException(Status.NOT_FOUND.withDescription("set essence message failed"))
|
throw StatusRuntimeException(Status.NOT_FOUND.withDescription("set essence message failed"))
|
||||||
}
|
}
|
||||||
return setEssenceMessageResponse { }
|
return SetEssenceMessageResponse.newBuilder().build()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Grpc("MessageService", "SetMessageCommentEmoji")
|
@Grpc("MessageService", "SetMessageCommentEmoji")
|
||||||
override suspend fun setMessageCommentEmoji(request: SetMessageCommentEmojiRequest): SetMessageCommentEmojiResponse {
|
override suspend fun setMessageCommentEmoji(request: SetMessageCommentEmojiRequest): SetMessageCommentEmojiResponse {
|
||||||
val contact = request.contact.let {
|
val contact = request.contact.let {
|
||||||
MessageHelper.generateContact(when(it.scene!!) {
|
MessageHelper.generateContact(
|
||||||
|
when (it.scene!!) {
|
||||||
Scene.GROUP -> MsgConstant.KCHATTYPEGROUP
|
Scene.GROUP -> MsgConstant.KCHATTYPEGROUP
|
||||||
Scene.FRIEND -> MsgConstant.KCHATTYPEC2C
|
Scene.FRIEND -> MsgConstant.KCHATTYPEC2C
|
||||||
Scene.GUILD -> MsgConstant.KCHATTYPEGUILD
|
Scene.GUILD -> MsgConstant.KCHATTYPEGUILD
|
||||||
@ -446,7 +378,8 @@ internal object MessageService: MessageServiceGrpcKt.MessageServiceCoroutineImpl
|
|||||||
Scene.NEARBY -> MsgConstant.KCHATTYPETEMPC2CFROMUNKNOWN
|
Scene.NEARBY -> MsgConstant.KCHATTYPETEMPC2CFROMUNKNOWN
|
||||||
Scene.STRANGER -> MsgConstant.KCHATTYPETEMPC2CFROMUNKNOWN
|
Scene.STRANGER -> MsgConstant.KCHATTYPETEMPC2CFROMUNKNOWN
|
||||||
Scene.UNRECOGNIZED -> throw StatusRuntimeException(Status.INVALID_ARGUMENT.withDescription("Unrecognized scene"))
|
Scene.UNRECOGNIZED -> throw StatusRuntimeException(Status.INVALID_ARGUMENT.withDescription("Unrecognized scene"))
|
||||||
}, it.peer, it.subPeer)
|
}, it.peer, it.subPeer
|
||||||
|
)
|
||||||
}
|
}
|
||||||
val msg: MsgRecord = withTimeoutOrNull(5000) {
|
val msg: MsgRecord = withTimeoutOrNull(5000) {
|
||||||
val service = QRoute.api(IMsgService::class.java)
|
val service = QRoute.api(IMsgService::class.java)
|
||||||
@ -463,7 +396,12 @@ internal object MessageService: MessageServiceGrpcKt.MessageServiceCoroutineImpl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} ?: throw StatusRuntimeException(Status.NOT_FOUND.withDescription("Message not found"))
|
} ?: throw StatusRuntimeException(Status.NOT_FOUND.withDescription("Message not found"))
|
||||||
MessageHelper.setGroupMessageCommentFace(request.contact.longPeer(), msg.msgSeq.toULong(), request.faceId.toString(), request.isComment)
|
MessageHelper.setGroupMessageCommentFace(
|
||||||
return setMessageCommentEmojiResponse { }
|
request.contact.longPeer(),
|
||||||
|
msg.msgSeq.toULong(),
|
||||||
|
request.faceId.toString(),
|
||||||
|
request.isComment
|
||||||
|
)
|
||||||
|
return SetMessageCommentEmojiResponse.newBuilder().build()
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -2,36 +2,24 @@ package kritor.service
|
|||||||
|
|
||||||
import io.grpc.Status
|
import io.grpc.Status
|
||||||
import io.grpc.StatusRuntimeException
|
import io.grpc.StatusRuntimeException
|
||||||
import io.kritor.web.GetCSRFTokenRequest
|
import io.kritor.web.*
|
||||||
import io.kritor.web.GetCSRFTokenResponse
|
|
||||||
import io.kritor.web.GetCookiesRequest
|
|
||||||
import io.kritor.web.GetCookiesResponse
|
|
||||||
import io.kritor.web.GetCredentialsRequest
|
|
||||||
import io.kritor.web.GetCredentialsResponse
|
|
||||||
import io.kritor.web.GetHttpCookiesRequest
|
|
||||||
import io.kritor.web.GetHttpCookiesResponse
|
|
||||||
import io.kritor.web.WebServiceGrpcKt
|
|
||||||
import io.kritor.web.getCSRFTokenResponse
|
|
||||||
import io.kritor.web.getCookiesResponse
|
|
||||||
import io.kritor.web.getCredentialsResponse
|
|
||||||
import io.kritor.web.getHttpCookiesResponse
|
|
||||||
import qq.service.ticket.TicketHelper
|
import qq.service.ticket.TicketHelper
|
||||||
|
|
||||||
internal object WebService: WebServiceGrpcKt.WebServiceCoroutineImplBase() {
|
internal object WebService: WebServiceGrpcKt.WebServiceCoroutineImplBase() {
|
||||||
@Grpc("WebService", "GetCookies")
|
@Grpc("WebService", "GetCookies")
|
||||||
override suspend fun getCookies(request: GetCookiesRequest): GetCookiesResponse {
|
override suspend fun getCookies(request: GetCookiesRequest): GetCookiesResponse {
|
||||||
return getCookiesResponse {
|
return GetCookiesResponse.newBuilder().apply {
|
||||||
if (request.domain.isNullOrEmpty()) {
|
if (request.domain.isNullOrEmpty()) {
|
||||||
this.cookie = TicketHelper.getCookie()
|
this.cookie = TicketHelper.getCookie()
|
||||||
} else {
|
} else {
|
||||||
this.cookie = TicketHelper.getCookie(request.domain)
|
this.cookie = TicketHelper.getCookie(request.domain)
|
||||||
}
|
}
|
||||||
}
|
}.build()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Grpc("WebService", "GetCredentials")
|
@Grpc("WebService", "GetCredentials")
|
||||||
override suspend fun getCredentials(request: GetCredentialsRequest): GetCredentialsResponse {
|
override suspend fun getCredentials(request: GetCredentialsRequest): GetCredentialsResponse {
|
||||||
return getCredentialsResponse {
|
return GetCredentialsResponse.newBuilder().apply {
|
||||||
if (request.domain.isNullOrEmpty()) {
|
if (request.domain.isNullOrEmpty()) {
|
||||||
val uin = TicketHelper.getUin()
|
val uin = TicketHelper.getUin()
|
||||||
val skey = TicketHelper.getRealSkey(uin)
|
val skey = TicketHelper.getRealSkey(uin)
|
||||||
@ -46,27 +34,25 @@ internal object WebService: WebServiceGrpcKt.WebServiceCoroutineImplBase() {
|
|||||||
this.cookie = "o_cookie=$uin; ied_qq=o$uin; pac_uid=1_$uin; uin=o$uin; skey=$skey; p_uin=o$uin; p_skey=$pskey; pt4_token=$pt4token;"
|
this.cookie = "o_cookie=$uin; ied_qq=o$uin; pac_uid=1_$uin; uin=o$uin; skey=$skey; p_uin=o$uin; p_skey=$pskey; pt4_token=$pt4token;"
|
||||||
this.bkn = TicketHelper.getCSRF(pskey)
|
this.bkn = TicketHelper.getCSRF(pskey)
|
||||||
}
|
}
|
||||||
}
|
}.build()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Grpc("WebService", "GetCSRFToken")
|
@Grpc("WebService", "GetCSRFToken")
|
||||||
override suspend fun getCSRFToken(request: GetCSRFTokenRequest): GetCSRFTokenResponse {
|
override suspend fun getCSRFToken(request: GetCSRFTokenRequest): GetCSRFTokenResponse {
|
||||||
return getCSRFTokenResponse {
|
return GetCSRFTokenResponse.newBuilder().apply {
|
||||||
if (request.domain.isNullOrEmpty()) {
|
if (request.domain.isNullOrEmpty()) {
|
||||||
this.bkn = TicketHelper.getCSRF()
|
this.bkn = TicketHelper.getCSRF()
|
||||||
} else {
|
} else {
|
||||||
this.bkn = TicketHelper.getCSRF(TicketHelper.getUin(), request.domain)
|
this.bkn = TicketHelper.getCSRF(TicketHelper.getUin(), request.domain)
|
||||||
}
|
}
|
||||||
}
|
}.build()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Grpc("WebService", "GetHttpCookies")
|
@Grpc("WebService", "GetHttpCookies")
|
||||||
override suspend fun getHttpCookies(request: GetHttpCookiesRequest): GetHttpCookiesResponse {
|
override suspend fun getHttpCookies(request: GetHttpCookiesRequest): GetHttpCookiesResponse {
|
||||||
return getHttpCookiesResponse {
|
return GetHttpCookiesResponse.newBuilder().apply {
|
||||||
this.cookie = TicketHelper.getHttpCookies(request.appid, request.daid, request.jumpUrl)
|
this.cookie = TicketHelper.getHttpCookies(request.appid, request.daid, request.jumpUrl)
|
||||||
?: throw StatusRuntimeException(Status.INTERNAL.withDescription("unable to get http cookies"))
|
?: throw StatusRuntimeException(Status.INTERNAL.withDescription("unable to get http cookies"))
|
||||||
|
}.build()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
|
@ -4,37 +4,9 @@ package moe.fuqiuluo.shamrock.internals
|
|||||||
|
|
||||||
import com.tencent.qqnt.kernel.nativeinterface.MsgElement
|
import com.tencent.qqnt.kernel.nativeinterface.MsgElement
|
||||||
import com.tencent.qqnt.kernel.nativeinterface.MsgRecord
|
import com.tencent.qqnt.kernel.nativeinterface.MsgRecord
|
||||||
import io.kritor.event.GroupApplyType
|
import io.kritor.event.*
|
||||||
import io.kritor.event.GroupMemberBanType
|
import io.kritor.message.Contact
|
||||||
import io.kritor.event.GroupMemberDecreasedType
|
import io.kritor.message.Sender
|
||||||
import io.kritor.event.GroupMemberIncreasedType
|
|
||||||
import io.kritor.event.MessageEvent
|
|
||||||
import io.kritor.event.NoticeEvent
|
|
||||||
import io.kritor.event.NoticeType
|
|
||||||
import io.kritor.event.RequestType
|
|
||||||
import io.kritor.event.RequestsEvent
|
|
||||||
import io.kritor.event.Scene
|
|
||||||
import io.kritor.event.contact
|
|
||||||
import io.kritor.event.essenceMessageNotice
|
|
||||||
import io.kritor.event.friendApplyRequest
|
|
||||||
import io.kritor.event.friendFileComeNotice
|
|
||||||
import io.kritor.event.friendPokeNotice
|
|
||||||
import io.kritor.event.friendRecallNotice
|
|
||||||
import io.kritor.event.groupAdminChangedNotice
|
|
||||||
import io.kritor.event.groupApplyRequest
|
|
||||||
import io.kritor.event.groupFileComeNotice
|
|
||||||
import io.kritor.event.groupMemberBannedNotice
|
|
||||||
import io.kritor.event.groupMemberDecreasedNotice
|
|
||||||
import io.kritor.event.groupMemberIncreasedNotice
|
|
||||||
import io.kritor.event.groupPokeNotice
|
|
||||||
import io.kritor.event.groupRecallNotice
|
|
||||||
import io.kritor.event.groupSignNotice
|
|
||||||
import io.kritor.event.groupUniqueTitleChangedNotice
|
|
||||||
import io.kritor.event.groupWholeBanNotice
|
|
||||||
import io.kritor.event.messageEvent
|
|
||||||
import io.kritor.event.noticeEvent
|
|
||||||
import io.kritor.event.requestsEvent
|
|
||||||
import io.kritor.event.sender
|
|
||||||
import kotlinx.coroutines.DelicateCoroutinesApi
|
import kotlinx.coroutines.DelicateCoroutinesApi
|
||||||
import kotlinx.coroutines.GlobalScope
|
import kotlinx.coroutines.GlobalScope
|
||||||
import kotlinx.coroutines.flow.FlowCollector
|
import kotlinx.coroutines.flow.FlowCollector
|
||||||
@ -44,7 +16,7 @@ import qq.service.QQInterfaces
|
|||||||
import qq.service.msg.toKritorEventMessages
|
import qq.service.msg.toKritorEventMessages
|
||||||
|
|
||||||
internal object GlobalEventTransmitter : QQInterfaces() {
|
internal object GlobalEventTransmitter : QQInterfaces() {
|
||||||
private val messageEventFlow by lazy {
|
private val MessageEventFlow by lazy {
|
||||||
MutableSharedFlow<Pair<MsgRecord, MessageEvent>>()
|
MutableSharedFlow<Pair<MsgRecord, MessageEvent>>()
|
||||||
}
|
}
|
||||||
private val noticeEventFlow by lazy {
|
private val noticeEventFlow by lazy {
|
||||||
@ -58,30 +30,30 @@ internal object GlobalEventTransmitter: QQInterfaces() {
|
|||||||
|
|
||||||
private suspend fun pushRequest(requestEvent: RequestsEvent) = requestEventFlow.emit(requestEvent)
|
private suspend fun pushRequest(requestEvent: RequestsEvent) = requestEventFlow.emit(requestEvent)
|
||||||
|
|
||||||
private suspend fun transMessageEvent(record: MsgRecord, message: MessageEvent) = messageEventFlow.emit(record to message)
|
private suspend fun transMessageEvent(record: MsgRecord, message: MessageEvent) =
|
||||||
|
MessageEventFlow.emit(record to message)
|
||||||
|
|
||||||
object MessageTransmitter {
|
object MessageTransmitter {
|
||||||
suspend fun transGroupMessage(
|
suspend fun transGroupMessage(
|
||||||
record: MsgRecord,
|
record: MsgRecord,
|
||||||
elements: ArrayList<MsgElement>,
|
elements: ArrayList<MsgElement>,
|
||||||
): Boolean {
|
): Boolean {
|
||||||
transMessageEvent(record, messageEvent {
|
transMessageEvent(record, MessageEvent.newBuilder().apply {
|
||||||
this.time = record.msgTime.toInt()
|
this.time = record.msgTime.toInt()
|
||||||
this.scene = Scene.GROUP
|
|
||||||
this.messageId = record.msgId
|
this.messageId = record.msgId
|
||||||
this.messageSeq = record.msgSeq
|
this.messageSeq = record.msgSeq
|
||||||
this.contact = contact {
|
this.contact = Contact.newBuilder().apply {
|
||||||
this.scene = scene
|
this.scene = scene
|
||||||
this.peer = record.peerUin.toString()
|
this.peer = record.peerUin.toString()
|
||||||
this.subPeer = record.peerUid
|
this.subPeer = record.peerUid
|
||||||
}
|
}.build()
|
||||||
this.sender = sender {
|
this.sender = Sender.newBuilder().apply {
|
||||||
this.uin = record.senderUin
|
this.uin = record.senderUin
|
||||||
this.uid = record.senderUid
|
this.uid = record.senderUid
|
||||||
this.nick = record.sendNickName
|
this.nick = record.sendNickName
|
||||||
}
|
}.build()
|
||||||
this.elements.addAll(elements.toKritorEventMessages(record))
|
this.addAllElements(elements.toKritorEventMessages(record))
|
||||||
})
|
}.build())
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -89,23 +61,22 @@ internal object GlobalEventTransmitter: QQInterfaces() {
|
|||||||
record: MsgRecord,
|
record: MsgRecord,
|
||||||
elements: ArrayList<MsgElement>,
|
elements: ArrayList<MsgElement>,
|
||||||
): Boolean {
|
): Boolean {
|
||||||
transMessageEvent(record, messageEvent {
|
transMessageEvent(record, MessageEvent.newBuilder().apply {
|
||||||
this.time = record.msgTime.toInt()
|
this.time = record.msgTime.toInt()
|
||||||
this.scene = Scene.FRIEND
|
|
||||||
this.messageId = record.msgId
|
this.messageId = record.msgId
|
||||||
this.messageSeq = record.msgSeq
|
this.messageSeq = record.msgSeq
|
||||||
this.contact = contact {
|
this.contact = Contact.newBuilder().apply {
|
||||||
this.scene = scene
|
this.scene = scene
|
||||||
this.peer = record.senderUin.toString()
|
this.peer = record.senderUin.toString()
|
||||||
this.subPeer = record.senderUid
|
this.subPeer = record.senderUid
|
||||||
}
|
}.build()
|
||||||
this.sender = sender {
|
this.sender = Sender.newBuilder().apply {
|
||||||
this.uin = record.senderUin
|
this.uin = record.senderUin
|
||||||
this.uid = record.senderUid
|
this.uid = record.senderUid
|
||||||
this.nick = record.sendNickName
|
this.nick = record.sendNickName
|
||||||
}
|
}.build()
|
||||||
this.elements.addAll(elements.toKritorEventMessages(record))
|
this.addAllElements(elements.toKritorEventMessages(record))
|
||||||
})
|
}.build())
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -115,23 +86,22 @@ internal object GlobalEventTransmitter: QQInterfaces() {
|
|||||||
groupCode: Long,
|
groupCode: Long,
|
||||||
fromNick: String,
|
fromNick: String,
|
||||||
): Boolean {
|
): Boolean {
|
||||||
transMessageEvent(record, messageEvent {
|
transMessageEvent(record, MessageEvent.newBuilder().apply {
|
||||||
this.time = record.msgTime.toInt()
|
this.time = record.msgTime.toInt()
|
||||||
this.scene = Scene.FRIEND
|
|
||||||
this.messageId = record.msgId
|
this.messageId = record.msgId
|
||||||
this.messageSeq = record.msgSeq
|
this.messageSeq = record.msgSeq
|
||||||
this.contact = contact {
|
this.contact = Contact.newBuilder().apply {
|
||||||
this.scene = scene
|
this.scene = scene
|
||||||
this.peer = record.senderUin.toString()
|
this.peer = record.senderUin.toString()
|
||||||
this.subPeer = groupCode.toString()
|
this.subPeer = groupCode.toString()
|
||||||
}
|
}.build()
|
||||||
this.sender = sender {
|
this.sender = Sender.newBuilder().apply {
|
||||||
this.uin = record.senderUin
|
this.uin = record.senderUin
|
||||||
this.uid = record.senderUid
|
this.uid = record.senderUid
|
||||||
this.nick = record.sendNickName
|
this.nick = record.sendNickName
|
||||||
}
|
}.build()
|
||||||
this.elements.addAll(elements.toKritorEventMessages(record))
|
this.addAllElements(elements.toKritorEventMessages(record))
|
||||||
})
|
}.build())
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -139,23 +109,22 @@ internal object GlobalEventTransmitter: QQInterfaces() {
|
|||||||
record: MsgRecord,
|
record: MsgRecord,
|
||||||
elements: ArrayList<MsgElement>,
|
elements: ArrayList<MsgElement>,
|
||||||
): Boolean {
|
): Boolean {
|
||||||
transMessageEvent(record, messageEvent {
|
transMessageEvent(record, MessageEvent.newBuilder().apply {
|
||||||
this.time = record.msgTime.toInt()
|
this.time = record.msgTime.toInt()
|
||||||
this.scene = Scene.GUILD
|
|
||||||
this.messageId = record.msgId
|
this.messageId = record.msgId
|
||||||
this.messageSeq = record.msgSeq
|
this.messageSeq = record.msgSeq
|
||||||
this.contact = contact {
|
this.contact = Contact.newBuilder().apply {
|
||||||
this.scene = scene
|
this.scene = scene
|
||||||
this.peer = record.guildId ?: ""
|
this.peer = record.guildId ?: ""
|
||||||
this.subPeer = record.channelId ?: ""
|
this.subPeer = record.channelId ?: ""
|
||||||
}
|
}.build()
|
||||||
this.sender = sender {
|
this.sender = Sender.newBuilder().apply {
|
||||||
this.uin = record.senderUin
|
this.uin = record.senderUin
|
||||||
this.uid = record.senderUid
|
this.uid = record.senderUid
|
||||||
this.nick = record.sendNickName
|
this.nick = record.sendNickName
|
||||||
}
|
}.build()
|
||||||
this.elements.addAll(elements.toKritorEventMessages(record))
|
this.addAllElements(elements.toKritorEventMessages(record))
|
||||||
})
|
}.build())
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -177,10 +146,10 @@ internal object GlobalEventTransmitter: QQInterfaces() {
|
|||||||
expireTime: Long,
|
expireTime: Long,
|
||||||
url: String
|
url: String
|
||||||
): Boolean {
|
): Boolean {
|
||||||
pushNotice(noticeEvent {
|
pushNotice(NoticeEvent.newBuilder().apply {
|
||||||
this.type = NoticeType.FRIEND_FILE_COME
|
this.type = NoticeType.FRIEND_FILE_COME
|
||||||
this.time = msgTime.toInt()
|
this.time = msgTime.toInt()
|
||||||
this.friendFileCome = friendFileComeNotice {
|
this.friendFileCome = FriendFileComeNotice.newBuilder().apply {
|
||||||
this.fileId = fileId
|
this.fileId = fileId
|
||||||
this.fileName = fileName
|
this.fileName = fileName
|
||||||
this.operator = userId
|
this.operator = userId
|
||||||
@ -188,8 +157,8 @@ internal object GlobalEventTransmitter: QQInterfaces() {
|
|||||||
this.expireTime = expireTime.toInt()
|
this.expireTime = expireTime.toInt()
|
||||||
this.fileSubId = fileSubId
|
this.fileSubId = fileSubId
|
||||||
this.url = url
|
this.url = url
|
||||||
}
|
}.build()
|
||||||
})
|
}.build())
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -206,10 +175,10 @@ internal object GlobalEventTransmitter: QQInterfaces() {
|
|||||||
bizId: Int,
|
bizId: Int,
|
||||||
url: String
|
url: String
|
||||||
): Boolean {
|
): Boolean {
|
||||||
pushNotice(noticeEvent {
|
pushNotice(NoticeEvent.newBuilder().apply {
|
||||||
this.type = NoticeType.GROUP_FILE_COME
|
this.type = NoticeType.GROUP_FILE_COME
|
||||||
this.time = msgTime.toInt()
|
this.time = msgTime.toInt()
|
||||||
this.groupFileCome = groupFileComeNotice {
|
this.groupFileCome = GroupFileComeNotice.newBuilder().apply {
|
||||||
this.groupId = groupId
|
this.groupId = groupId
|
||||||
this.operator = userId
|
this.operator = userId
|
||||||
this.fileId = uuid
|
this.fileId = uuid
|
||||||
@ -217,8 +186,8 @@ internal object GlobalEventTransmitter: QQInterfaces() {
|
|||||||
this.fileSize = fileSize
|
this.fileSize = fileSize
|
||||||
this.biz = bizId
|
this.biz = bizId
|
||||||
this.url = url
|
this.url = url
|
||||||
}
|
}.build()
|
||||||
})
|
}.build())
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -227,33 +196,47 @@ internal object GlobalEventTransmitter: QQInterfaces() {
|
|||||||
* 群聊通知 通知器
|
* 群聊通知 通知器
|
||||||
*/
|
*/
|
||||||
object GroupNoticeTransmitter {
|
object GroupNoticeTransmitter {
|
||||||
suspend fun transGroupSign(time: Long, target: Long, action: String?, rankImg: String?, groupCode: Long): Boolean {
|
suspend fun transGroupSign(
|
||||||
pushNotice(noticeEvent {
|
time: Long,
|
||||||
|
target: Long,
|
||||||
|
action: String?,
|
||||||
|
rankImg: String?,
|
||||||
|
groupCode: Long
|
||||||
|
): Boolean {
|
||||||
|
pushNotice(NoticeEvent.newBuilder().apply {
|
||||||
this.type = NoticeType.GROUP_SIGN
|
this.type = NoticeType.GROUP_SIGN
|
||||||
this.time = time.toInt()
|
this.time = time.toInt()
|
||||||
this.groupSign = groupSignNotice {
|
this.groupSign = GroupSignNotice.newBuilder().apply {
|
||||||
this.groupId = groupCode
|
this.groupId = groupCode
|
||||||
this.targetUin = target
|
this.targetUin = target
|
||||||
this.action = action ?: ""
|
this.action = action ?: ""
|
||||||
this.suffix = ""
|
this.suffix = ""
|
||||||
this.rankImage = rankImg ?: ""
|
this.rankImage = rankImg ?: ""
|
||||||
}
|
}.build()
|
||||||
})
|
}.build())
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun transGroupPoke(time: Long, operator: Long, target: Long, action: String?, suffix: String?, actionImg: String?, groupCode: Long): Boolean {
|
suspend fun transGroupPoke(
|
||||||
pushNotice(noticeEvent {
|
time: Long,
|
||||||
|
operator: Long,
|
||||||
|
target: Long,
|
||||||
|
action: String?,
|
||||||
|
suffix: String?,
|
||||||
|
actionImg: String?,
|
||||||
|
groupCode: Long
|
||||||
|
): Boolean {
|
||||||
|
pushNotice(NoticeEvent.newBuilder().apply {
|
||||||
this.type = NoticeType.GROUP_POKE
|
this.type = NoticeType.GROUP_POKE
|
||||||
this.time = time.toInt()
|
this.time = time.toInt()
|
||||||
this.groupPoke = groupPokeNotice {
|
this.groupPoke = GroupPokeNotice.newBuilder().apply {
|
||||||
this.action = action ?: ""
|
this.action = action ?: ""
|
||||||
this.target = target
|
this.target = target
|
||||||
this.operator = operator
|
this.operator = operator
|
||||||
this.suffix = suffix ?: ""
|
this.suffix = suffix ?: ""
|
||||||
this.actionImage = actionImg ?: ""
|
this.actionImage = actionImg ?: ""
|
||||||
}
|
}.build()
|
||||||
})
|
}.build())
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -266,18 +249,18 @@ internal object GlobalEventTransmitter: QQInterfaces() {
|
|||||||
operatorUid: String,
|
operatorUid: String,
|
||||||
type: GroupMemberIncreasedType
|
type: GroupMemberIncreasedType
|
||||||
): Boolean {
|
): Boolean {
|
||||||
pushNotice(noticeEvent {
|
pushNotice(NoticeEvent.newBuilder().apply {
|
||||||
this.type = NoticeType.GROUP_MEMBER_INCREASE
|
this.type = NoticeType.GROUP_MEMBER_INCREASE
|
||||||
this.time = time.toInt()
|
this.time = time.toInt()
|
||||||
this.groupMemberIncrease = groupMemberIncreasedNotice {
|
this.groupMemberIncrease = GroupMemberIncreasedNotice.newBuilder().apply {
|
||||||
this.groupId = groupCode
|
this.groupId = groupCode
|
||||||
this.operatorUid = operatorUid
|
this.operatorUid = operatorUid
|
||||||
this.operatorUin = operator
|
this.operatorUin = operator
|
||||||
this.targetUid = targetUid
|
this.targetUid = targetUid
|
||||||
this.targetUin = target
|
this.targetUin = target
|
||||||
this.type = type
|
this.type = type
|
||||||
}
|
}.build()
|
||||||
})
|
}.build())
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -290,18 +273,18 @@ internal object GlobalEventTransmitter: QQInterfaces() {
|
|||||||
operatorUid: String,
|
operatorUid: String,
|
||||||
type: GroupMemberDecreasedType
|
type: GroupMemberDecreasedType
|
||||||
): Boolean {
|
): Boolean {
|
||||||
pushNotice(noticeEvent {
|
pushNotice(NoticeEvent.newBuilder().apply {
|
||||||
this.type = NoticeType.GROUP_MEMBER_INCREASE
|
this.type = NoticeType.GROUP_MEMBER_INCREASE
|
||||||
this.time = time.toInt()
|
this.time = time.toInt()
|
||||||
this.groupMemberDecrease = groupMemberDecreasedNotice {
|
this.groupMemberDecrease = GroupMemberDecreasedNotice.newBuilder().apply {
|
||||||
this.groupId = groupCode
|
this.groupId = groupCode
|
||||||
this.operatorUid = operatorUid
|
this.operatorUid = operatorUid
|
||||||
this.operatorUin = operator
|
this.operatorUin = operator
|
||||||
this.targetUid = targetUid
|
this.targetUid = targetUid
|
||||||
this.targetUin = target
|
this.targetUin = target
|
||||||
this.type = type
|
this.type = type
|
||||||
}
|
}.build()
|
||||||
})
|
}.build())
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -312,16 +295,16 @@ internal object GlobalEventTransmitter: QQInterfaces() {
|
|||||||
groupCode: Long,
|
groupCode: Long,
|
||||||
setAdmin: Boolean
|
setAdmin: Boolean
|
||||||
): Boolean {
|
): Boolean {
|
||||||
pushNotice(noticeEvent {
|
pushNotice(NoticeEvent.newBuilder().apply {
|
||||||
this.type = NoticeType.GROUP_ADMIN_CHANGED
|
this.type = NoticeType.GROUP_ADMIN_CHANGED
|
||||||
this.time = msgTime.toInt()
|
this.time = msgTime.toInt()
|
||||||
this.groupAdminChanged = groupAdminChangedNotice {
|
this.groupAdminChanged = GroupAdminChangedNotice.newBuilder().apply {
|
||||||
this.groupId = groupCode
|
this.groupId = groupCode
|
||||||
this.targetUid = targetUid
|
this.targetUid = targetUid
|
||||||
this.targetUin = target
|
this.targetUin = target
|
||||||
this.isAdmin = setAdmin
|
this.isAdmin = setAdmin
|
||||||
}
|
}.build()
|
||||||
})
|
}.build())
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -331,15 +314,15 @@ internal object GlobalEventTransmitter: QQInterfaces() {
|
|||||||
groupCode: Long,
|
groupCode: Long,
|
||||||
isOpen: Boolean
|
isOpen: Boolean
|
||||||
): Boolean {
|
): Boolean {
|
||||||
pushNotice(noticeEvent {
|
pushNotice(NoticeEvent.newBuilder().apply {
|
||||||
this.type = NoticeType.GROUP_WHOLE_BAN
|
this.type = NoticeType.GROUP_WHOLE_BAN
|
||||||
this.time = msgTime.toInt()
|
this.time = msgTime.toInt()
|
||||||
this.groupWholeBan = groupWholeBanNotice {
|
this.groupWholeBan = GroupWholeBanNotice.newBuilder().apply {
|
||||||
this.groupId = groupCode
|
this.groupId = groupCode
|
||||||
this.isWholeBan = isOpen
|
this.isWholeBan = isOpen
|
||||||
this.operator = operator
|
this.operator = operator
|
||||||
}
|
}.build()
|
||||||
})
|
}.build())
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -352,10 +335,10 @@ internal object GlobalEventTransmitter: QQInterfaces() {
|
|||||||
groupCode: Long,
|
groupCode: Long,
|
||||||
duration: Int
|
duration: Int
|
||||||
): Boolean {
|
): Boolean {
|
||||||
pushNotice(noticeEvent {
|
pushNotice(NoticeEvent.newBuilder().apply {
|
||||||
this.type = NoticeType.GROUP_MEMBER_BANNED
|
this.type = NoticeType.GROUP_MEMBER_BANNED
|
||||||
this.time = msgTime.toInt()
|
this.time = msgTime.toInt()
|
||||||
this.groupMemberBanned = groupMemberBannedNotice {
|
this.groupMemberBanned = GroupMemberBannedNotice.newBuilder().apply {
|
||||||
this.groupId = groupCode
|
this.groupId = groupCode
|
||||||
this.operatorUid = operatorUid
|
this.operatorUid = operatorUid
|
||||||
this.operatorUin = operator
|
this.operatorUin = operator
|
||||||
@ -364,8 +347,8 @@ internal object GlobalEventTransmitter: QQInterfaces() {
|
|||||||
this.duration = duration
|
this.duration = duration
|
||||||
this.type = if (duration > 0) GroupMemberBanType.BAN
|
this.type = if (duration > 0) GroupMemberBanType.BAN
|
||||||
else GroupMemberBanType.LIFT_BAN
|
else GroupMemberBanType.LIFT_BAN
|
||||||
}
|
}.build()
|
||||||
})
|
}.build())
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -379,10 +362,10 @@ internal object GlobalEventTransmitter: QQInterfaces() {
|
|||||||
msgId: Long,
|
msgId: Long,
|
||||||
tipText: String
|
tipText: String
|
||||||
): Boolean {
|
): Boolean {
|
||||||
pushNotice(noticeEvent {
|
pushNotice(NoticeEvent.newBuilder().apply {
|
||||||
this.type = NoticeType.GROUP_RECALL
|
this.type = NoticeType.GROUP_RECALL
|
||||||
this.time = time.toInt()
|
this.time = time.toInt()
|
||||||
this.groupRecall = groupRecallNotice {
|
this.groupRecall = GroupRecallNotice.newBuilder().apply {
|
||||||
this.groupId = groupCode
|
this.groupId = groupCode
|
||||||
this.operatorUid = operatorUid
|
this.operatorUid = operatorUid
|
||||||
this.operatorUin = operator
|
this.operatorUin = operator
|
||||||
@ -390,8 +373,8 @@ internal object GlobalEventTransmitter: QQInterfaces() {
|
|||||||
this.targetUin = target
|
this.targetUin = target
|
||||||
this.messageId = msgId
|
this.messageId = msgId
|
||||||
this.tipText = tipText
|
this.tipText = tipText
|
||||||
}
|
}.build()
|
||||||
})
|
}.build())
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -412,15 +395,15 @@ internal object GlobalEventTransmitter: QQInterfaces() {
|
|||||||
title: String,
|
title: String,
|
||||||
groupId: Long
|
groupId: Long
|
||||||
): Boolean {
|
): Boolean {
|
||||||
pushNotice(noticeEvent {
|
pushNotice(NoticeEvent.newBuilder().apply {
|
||||||
this.type = NoticeType.GROUP_MEMBER_UNIQUE_TITLE_CHANGED
|
this.type = NoticeType.GROUP_MEMBER_UNIQUE_TITLE_CHANGED
|
||||||
this.time = time.toInt()
|
this.time = time.toInt()
|
||||||
this.groupMemberUniqueTitleChanged = groupUniqueTitleChangedNotice {
|
this.groupMemberUniqueTitleChanged = GroupUniqueTitleChangedNotice.newBuilder().apply {
|
||||||
this.groupId = groupId
|
this.groupId = groupId
|
||||||
this.target = targetId
|
this.target = targetId
|
||||||
this.title = title
|
this.title = title
|
||||||
}
|
}.build()
|
||||||
})
|
}.build())
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -432,17 +415,17 @@ internal object GlobalEventTransmitter: QQInterfaces() {
|
|||||||
groupId: Long,
|
groupId: Long,
|
||||||
subType: UInt
|
subType: UInt
|
||||||
): Boolean {
|
): Boolean {
|
||||||
pushNotice(noticeEvent {
|
pushNotice(NoticeEvent.newBuilder().apply {
|
||||||
this.type = NoticeType.GROUP_ESSENCE_CHANGED
|
this.type = NoticeType.GROUP_ESSENCE_CHANGED
|
||||||
this.time = time.toInt()
|
this.time = time.toInt()
|
||||||
this.groupEssenceChanged = essenceMessageNotice {
|
this.groupEssenceChanged = EssenceMessageNotice.newBuilder().apply {
|
||||||
this.groupId = groupId
|
this.groupId = groupId
|
||||||
this.messageId = msgId
|
this.messageId = msgId
|
||||||
this.sender = senderUin
|
this.sender = senderUin
|
||||||
this.operator = operatorUin
|
this.operator = operatorUin
|
||||||
this.subType = subType.toInt()
|
this.subType = subType.toInt()
|
||||||
}
|
}.build()
|
||||||
})
|
}.build())
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -451,31 +434,38 @@ internal object GlobalEventTransmitter: QQInterfaces() {
|
|||||||
* 私聊通知 通知器
|
* 私聊通知 通知器
|
||||||
*/
|
*/
|
||||||
object PrivateNoticeTransmitter {
|
object PrivateNoticeTransmitter {
|
||||||
suspend fun transPrivatePoke(msgTime: Long, operator: Long, target: Long, action: String?, suffix: String?, actionImg: String?): Boolean {
|
suspend fun transPrivatePoke(
|
||||||
pushNotice(noticeEvent {
|
msgTime: Long,
|
||||||
|
operator: Long,
|
||||||
|
target: Long,
|
||||||
|
action: String?,
|
||||||
|
suffix: String?,
|
||||||
|
actionImg: String?
|
||||||
|
): Boolean {
|
||||||
|
pushNotice(NoticeEvent.newBuilder().apply {
|
||||||
this.type = NoticeType.FRIEND_POKE
|
this.type = NoticeType.FRIEND_POKE
|
||||||
this.time = msgTime.toInt()
|
this.time = msgTime.toInt()
|
||||||
this.friendPoke = friendPokeNotice {
|
this.friendPoke = FriendPokeNotice.newBuilder().apply {
|
||||||
this.action = action ?: ""
|
this.action = action ?: ""
|
||||||
this.target = target
|
this.target = target
|
||||||
this.operator = operator
|
this.operator = operator
|
||||||
this.suffix = suffix ?: ""
|
this.suffix = suffix ?: ""
|
||||||
this.actionImage = actionImg ?: ""
|
this.actionImage = actionImg ?: ""
|
||||||
}
|
}.build()
|
||||||
})
|
}.build())
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun transPrivateRecall(time: Long, operator: Long, msgId: Long, tipText: String): Boolean {
|
suspend fun transPrivateRecall(time: Long, operator: Long, msgId: Long, tipText: String): Boolean {
|
||||||
pushNotice(noticeEvent {
|
pushNotice(NoticeEvent.newBuilder().apply {
|
||||||
this.type = NoticeType.FRIEND_RECALL
|
this.type = NoticeType.FRIEND_RECALL
|
||||||
this.time = time.toInt()
|
this.time = time.toInt()
|
||||||
this.friendRecall = friendRecallNotice {
|
this.friendRecall = FriendRecallNotice.newBuilder().apply {
|
||||||
this.operator = operator
|
this.operator = operator
|
||||||
this.messageId = msgId
|
this.messageId = msgId
|
||||||
this.tipText = tipText
|
this.tipText = tipText
|
||||||
}
|
}.build()
|
||||||
})
|
}.build())
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -486,15 +476,15 @@ internal object GlobalEventTransmitter: QQInterfaces() {
|
|||||||
*/
|
*/
|
||||||
object RequestTransmitter {
|
object RequestTransmitter {
|
||||||
suspend fun transFriendApp(time: Long, operator: Long, tipText: String, flag: String): Boolean {
|
suspend fun transFriendApp(time: Long, operator: Long, tipText: String, flag: String): Boolean {
|
||||||
pushRequest(requestsEvent {
|
pushRequest(RequestsEvent.newBuilder().apply {
|
||||||
this.type = RequestType.FRIEND_APPLY
|
this.type = RequestType.FRIEND_APPLY
|
||||||
this.time = time.toInt()
|
this.time = time.toInt()
|
||||||
this.friendApply = friendApplyRequest {
|
this.friendApply = FriendApplyRequest.newBuilder().apply {
|
||||||
this.applierUin = operator
|
this.applierUin = operator
|
||||||
this.message = tipText
|
this.message = tipText
|
||||||
this.flag = flag
|
this.flag = flag
|
||||||
}
|
}.build()
|
||||||
})
|
}.build())
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -507,24 +497,24 @@ internal object GlobalEventTransmitter: QQInterfaces() {
|
|||||||
flag: String,
|
flag: String,
|
||||||
type: GroupApplyType
|
type: GroupApplyType
|
||||||
): Boolean {
|
): Boolean {
|
||||||
pushRequest(requestsEvent {
|
pushRequest(RequestsEvent.newBuilder().apply {
|
||||||
this.type = RequestType.GROUP_APPLY
|
this.type = RequestType.GROUP_APPLY
|
||||||
this.time = time.toInt()
|
this.time = time.toInt()
|
||||||
this.groupApply = groupApplyRequest {
|
this.groupApply = GroupApplyRequest.newBuilder().apply {
|
||||||
this.applierUid = applierUid
|
this.applierUid = applierUid
|
||||||
this.applierUin = applier
|
this.applierUin = applier
|
||||||
this.groupId = groupCode
|
this.groupId = groupCode
|
||||||
this.reason = reason
|
this.reason = reason
|
||||||
this.flag = flag
|
this.flag = flag
|
||||||
this.type = type
|
this.type = type
|
||||||
}
|
}.build()
|
||||||
})
|
}.build())
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend inline fun onMessageEvent(collector: FlowCollector<Pair<MsgRecord, MessageEvent>>) {
|
suspend inline fun onMessageEvent(collector: FlowCollector<Pair<MsgRecord, MessageEvent>>) {
|
||||||
messageEventFlow.collect {
|
MessageEventFlow.collect {
|
||||||
GlobalScope.launch {
|
GlobalScope.launch {
|
||||||
collector.emit(it)
|
collector.emit(it)
|
||||||
}
|
}
|
||||||
|
@ -10,10 +10,6 @@ import io.kritor.file.Folder
|
|||||||
import io.kritor.file.GetFileSystemInfoResponse
|
import io.kritor.file.GetFileSystemInfoResponse
|
||||||
import io.kritor.file.GetFilesRequest
|
import io.kritor.file.GetFilesRequest
|
||||||
import io.kritor.file.GetFilesResponse
|
import io.kritor.file.GetFilesResponse
|
||||||
import io.kritor.file.folder
|
|
||||||
import io.kritor.file.getFileSystemInfoResponse
|
|
||||||
import io.kritor.file.getFilesRequest
|
|
||||||
import io.kritor.file.getFilesResponse
|
|
||||||
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.EMPTY_BYTE_ARRAY
|
import moe.fuqiuluo.shamrock.tools.EMPTY_BYTE_ARRAY
|
||||||
@ -73,12 +69,12 @@ internal object GroupFileHelper: QQInterfaces() {
|
|||||||
throw StatusRuntimeException(Status.INTERNAL.withDescription("unable to fetch oidb response x2"))
|
throw StatusRuntimeException(Status.INTERNAL.withDescription("unable to fetch oidb response x2"))
|
||||||
}
|
}
|
||||||
|
|
||||||
return getFileSystemInfoResponse {
|
return GetFileSystemInfoResponse.newBuilder().apply {
|
||||||
this.fileCount = fileCnt
|
this.fileCount = fileCnt
|
||||||
this.totalCount = limitCnt
|
this.totalCount = limitCnt
|
||||||
this.totalSpace = totalSpace.toInt()
|
this.totalSpace = totalSpace.toInt()
|
||||||
this.usedSpace = usedSpace.toInt()
|
this.usedSpace = usedSpace.toInt()
|
||||||
}
|
}.build()
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun getGroupFiles(groupId: Long, folderId: String = "/"): GetFilesResponse {
|
suspend fun getGroupFiles(groupId: Long, folderId: String = "/"): GetFilesResponse {
|
||||||
@ -108,7 +104,7 @@ internal object GroupFileHelper: QQInterfaces() {
|
|||||||
throw StatusRuntimeException(Status.INTERNAL.withDescription("oidb request failed"))
|
throw StatusRuntimeException(Status.INTERNAL.withDescription("oidb request failed"))
|
||||||
}
|
}
|
||||||
val files = arrayListOf<File>()
|
val files = arrayListOf<File>()
|
||||||
val dirs = arrayListOf<Folder>()
|
val folders = arrayListOf<Folder>()
|
||||||
if (fromServiceMsg.wupBuffer != null) {
|
if (fromServiceMsg.wupBuffer != null) {
|
||||||
val oidb = oidb_sso.OIDBSSOPkg().mergeFrom(fromServiceMsg.wupBuffer.slice(4).let {
|
val oidb = oidb_sso.OIDBSSOPkg().mergeFrom(fromServiceMsg.wupBuffer.slice(4).let {
|
||||||
if (it[0] == 0x78.toByte()) DeflateTools.uncompress(it) else it
|
if (it[0] == 0x78.toByte()) DeflateTools.uncompress(it) else it
|
||||||
@ -119,7 +115,7 @@ internal object GroupFileHelper: QQInterfaces() {
|
|||||||
rpt_item_list.get().forEach { file ->
|
rpt_item_list.get().forEach { file ->
|
||||||
if (file.uint32_type.get() == oidb_0x6d8.GetFileListRspBody.TYPE_FILE) {
|
if (file.uint32_type.get() == oidb_0x6d8.GetFileListRspBody.TYPE_FILE) {
|
||||||
val fileInfo = file.file_info
|
val fileInfo = file.file_info
|
||||||
files.add(io.kritor.file.file {
|
files.add(File.newBuilder().apply {
|
||||||
this.fileId = fileInfo.str_file_id.get()
|
this.fileId = fileInfo.str_file_id.get()
|
||||||
this.fileName = fileInfo.str_file_name.get()
|
this.fileName = fileInfo.str_file_name.get()
|
||||||
this.fileSize = fileInfo.uint64_file_size.get()
|
this.fileSize = fileInfo.uint64_file_size.get()
|
||||||
@ -133,18 +129,18 @@ internal object GroupFileHelper: QQInterfaces() {
|
|||||||
this.sha = fileInfo.bytes_sha.get().toByteArray().toHexString()
|
this.sha = fileInfo.bytes_sha.get().toByteArray().toHexString()
|
||||||
this.sha3 = fileInfo.bytes_sha3.get().toByteArray().toHexString()
|
this.sha3 = fileInfo.bytes_sha3.get().toByteArray().toHexString()
|
||||||
this.md5 = fileInfo.bytes_md5.get().toByteArray().toHexString()
|
this.md5 = fileInfo.bytes_md5.get().toByteArray().toHexString()
|
||||||
})
|
}.build())
|
||||||
}
|
}
|
||||||
else if (file.uint32_type.get() == oidb_0x6d8.GetFileListRspBody.TYPE_FOLDER) {
|
else if (file.uint32_type.get() == oidb_0x6d8.GetFileListRspBody.TYPE_FOLDER) {
|
||||||
val folderInfo = file.folder_info
|
val folderInfo = file.folder_info
|
||||||
dirs.add(folder {
|
folders.add(Folder.newBuilder().apply {
|
||||||
this.folderId = folderInfo.str_folder_id.get()
|
this.folderId = folderInfo.str_folder_id.get()
|
||||||
this.folderName = folderInfo.str_folder_name.get()
|
this.folderName = folderInfo.str_folder_name.get()
|
||||||
this.totalFileCount = folderInfo.uint32_total_file_count.get()
|
this.totalFileCount = folderInfo.uint32_total_file_count.get()
|
||||||
this.createTime = folderInfo.uint32_create_time.get()
|
this.createTime = folderInfo.uint32_create_time.get()
|
||||||
this.creator = folderInfo.uint64_create_uin.get()
|
this.creator = folderInfo.uint64_create_uin.get()
|
||||||
this.creatorName = folderInfo.str_creator_name.get()
|
this.creatorName = folderInfo.str_creator_name.get()
|
||||||
})
|
}.build())
|
||||||
} else {
|
} else {
|
||||||
LogCenter.log("未知文件类型: ${file.uint32_type.get()}", Level.WARN)
|
LogCenter.log("未知文件类型: ${file.uint32_type.get()}", Level.WARN)
|
||||||
}
|
}
|
||||||
@ -154,9 +150,9 @@ internal object GroupFileHelper: QQInterfaces() {
|
|||||||
throw StatusRuntimeException(Status.INTERNAL.withDescription("unable to fetch oidb response"))
|
throw StatusRuntimeException(Status.INTERNAL.withDescription("unable to fetch oidb response"))
|
||||||
}
|
}
|
||||||
|
|
||||||
return getFilesResponse {
|
return GetFilesResponse.newBuilder().apply {
|
||||||
this.files.addAll(files)
|
this.addAllFiles(files)
|
||||||
this.folders.addAll(folders)
|
this.addAllFolders(folders)
|
||||||
}
|
}.build()
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -6,14 +6,9 @@ import com.tencent.qqnt.kernel.nativeinterface.MsgRecord
|
|||||||
import com.tencent.qqnt.msg.api.IMsgService
|
import com.tencent.qqnt.msg.api.IMsgService
|
||||||
import io.grpc.Status
|
import io.grpc.Status
|
||||||
import io.grpc.StatusRuntimeException
|
import io.grpc.StatusRuntimeException
|
||||||
import io.kritor.message.Element
|
|
||||||
import io.kritor.message.ElementType
|
|
||||||
import io.kritor.message.ForwardElement
|
import io.kritor.message.ForwardElement
|
||||||
import io.kritor.message.ForwardMessageBody
|
import io.kritor.message.ForwardMessageBody
|
||||||
import io.kritor.message.Scene
|
import io.kritor.message.Scene
|
||||||
import io.kritor.message.forwardElement
|
|
||||||
import io.kritor.message.nodeOrNull
|
|
||||||
import io.kritor.message.senderOrNull
|
|
||||||
import kotlinx.coroutines.suspendCancellableCoroutine
|
import kotlinx.coroutines.suspendCancellableCoroutine
|
||||||
import kotlinx.coroutines.withTimeoutOrNull
|
import kotlinx.coroutines.withTimeoutOrNull
|
||||||
import moe.fuqiuluo.shamrock.helper.Level
|
import moe.fuqiuluo.shamrock.helper.Level
|
||||||
@ -28,7 +23,7 @@ import qq.service.QQInterfaces
|
|||||||
import qq.service.contact.ContactHelper
|
import qq.service.contact.ContactHelper
|
||||||
import qq.service.msg.MessageHelper.getMultiMsg
|
import qq.service.msg.MessageHelper.getMultiMsg
|
||||||
import qq.service.ticket.TicketHelper
|
import qq.service.ticket.TicketHelper
|
||||||
import java.util.UUID
|
import java.util.*
|
||||||
import kotlin.coroutines.resume
|
import kotlin.coroutines.resume
|
||||||
import kotlin.random.Random
|
import kotlin.random.Random
|
||||||
import kotlin.time.Duration.Companion.seconds
|
import kotlin.time.Duration.Companion.seconds
|
||||||
@ -47,7 +42,8 @@ internal object ForwardMessageHelper: QQInterfaces() {
|
|||||||
val msgs = messages.mapNotNull { msg ->
|
val msgs = messages.mapNotNull { msg ->
|
||||||
kotlin.runCatching {
|
kotlin.runCatching {
|
||||||
val contact = msg.contact.let {
|
val contact = msg.contact.let {
|
||||||
MessageHelper.generateContact(when(it.scene!!) {
|
MessageHelper.generateContact(
|
||||||
|
when (it.scene!!) {
|
||||||
Scene.GROUP -> MsgConstant.KCHATTYPEGROUP
|
Scene.GROUP -> MsgConstant.KCHATTYPEGROUP
|
||||||
Scene.FRIEND -> MsgConstant.KCHATTYPEC2C
|
Scene.FRIEND -> MsgConstant.KCHATTYPEC2C
|
||||||
Scene.GUILD -> MsgConstant.KCHATTYPEGUILD
|
Scene.GUILD -> MsgConstant.KCHATTYPEGUILD
|
||||||
@ -55,15 +51,17 @@ internal object ForwardMessageHelper: QQInterfaces() {
|
|||||||
Scene.NEARBY -> MsgConstant.KCHATTYPETEMPC2CFROMUNKNOWN
|
Scene.NEARBY -> MsgConstant.KCHATTYPETEMPC2CFROMUNKNOWN
|
||||||
Scene.STRANGER -> MsgConstant.KCHATTYPETEMPC2CFROMUNKNOWN
|
Scene.STRANGER -> MsgConstant.KCHATTYPETEMPC2CFROMUNKNOWN
|
||||||
Scene.UNRECOGNIZED -> throw StatusRuntimeException(Status.INVALID_ARGUMENT.withDescription("Unrecognized scene"))
|
Scene.UNRECOGNIZED -> throw StatusRuntimeException(Status.INVALID_ARGUMENT.withDescription("Unrecognized scene"))
|
||||||
}, it.peer, it.subPeer)
|
}, it.peer, it.subPeer
|
||||||
|
)
|
||||||
}
|
}
|
||||||
val node = msg.elementsList.find { it.type == ElementType.NODE }?.nodeOrNull
|
if (msg.hasMessageId()) {
|
||||||
if (node != null) {
|
|
||||||
val msgId = node.messageId
|
|
||||||
val record: MsgRecord = withTimeoutOrNull(5000) {
|
val record: MsgRecord = withTimeoutOrNull(5000) {
|
||||||
val service = QRoute.api(IMsgService::class.java)
|
val service = QRoute.api(IMsgService::class.java)
|
||||||
suspendCancellableCoroutine { continuation ->
|
suspendCancellableCoroutine { continuation ->
|
||||||
service.getMsgsByMsgId(contact, arrayListOf(msgId)) { code, _, msgRecords ->
|
service.getMsgsByMsgId(
|
||||||
|
contact,
|
||||||
|
arrayListOf(msg.messageId.toLong())
|
||||||
|
) { code, _, msgRecords ->
|
||||||
if (code == 0 && msgRecords.isNotEmpty()) {
|
if (code == 0 && msgRecords.isNotEmpty()) {
|
||||||
continuation.resume(msgRecords.first())
|
continuation.resume(msgRecords.first())
|
||||||
} else {
|
} else {
|
||||||
@ -74,7 +72,7 @@ internal object ForwardMessageHelper: QQInterfaces() {
|
|||||||
continuation.resume(null)
|
continuation.resume(null)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} ?: error("合并转发消息节点消息(id = $msgId)获取失败")
|
} ?: error("合并转发消息节点消息(id = ${msg.messageId})获取失败")
|
||||||
PushMsgBody(
|
PushMsgBody(
|
||||||
msgHead = ResponseHead(
|
msgHead = ResponseHead(
|
||||||
peerUid = record.senderUid,
|
peerUid = record.senderUid,
|
||||||
@ -121,12 +119,19 @@ internal object ForwardMessageHelper: QQInterfaces() {
|
|||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
PushMsgBody(
|
PushMsgBody(
|
||||||
msgHead = ResponseHead(
|
msgHead = if (msg.hasSender()) ResponseHead(
|
||||||
peer = msg.senderOrNull?.uin ?: TicketHelper.getUin().toLong(),
|
peer = if (msg.sender.hasUin()) msg.sender.uin else TicketHelper.getUin().toLong(),
|
||||||
peerUid = msg.senderOrNull?.uid ?: TicketHelper.getUid(),
|
peerUid = msg.sender.uid,
|
||||||
receiverUid = TicketHelper.getUid(),
|
receiverUid = TicketHelper.getUid(),
|
||||||
forward = ResponseForward(
|
forward = ResponseForward(
|
||||||
friendName = msg.senderOrNull?.nick ?: TicketHelper.getNickname()
|
friendName = if (msg.sender.hasNick()) msg.sender.nick else TicketHelper.getNickname()
|
||||||
|
)
|
||||||
|
) else ResponseHead(
|
||||||
|
peer = TicketHelper.getUin().toLong(),
|
||||||
|
peerUid = TicketHelper.getUid(),
|
||||||
|
receiverUid = TicketHelper.getUid(),
|
||||||
|
forward = ResponseForward(
|
||||||
|
friendName = TicketHelper.getNickname()
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
contentHead = ContentHead(
|
contentHead = ContentHead(
|
||||||
@ -150,7 +155,8 @@ internal object ForwardMessageHelper: QQInterfaces() {
|
|||||||
),
|
),
|
||||||
body = MsgBody(
|
body = MsgBody(
|
||||||
richText = msg.elementsList.toRichText(contact).onSuccess {
|
richText = msg.elementsList.toRichText(contact).onSuccess {
|
||||||
desc[++i] = (msg.senderOrNull?.nick ?: TicketHelper.getNickname()) + ": " + it.first
|
desc[++i] =
|
||||||
|
(if (msg.hasSender() && msg.sender.hasNick()) msg.sender.nick else TicketHelper.getNickname()) + ": " + it.first
|
||||||
}.onFailure {
|
}.onFailure {
|
||||||
error("消息合成失败: ${it.stackTraceToString()}")
|
error("消息合成失败: ${it.stackTraceToString()}")
|
||||||
}.getOrThrow().second
|
}.getOrThrow().second
|
||||||
@ -192,12 +198,14 @@ internal object ForwardMessageHelper: QQInterfaces() {
|
|||||||
uid = LongMsgUid(if (peerId.startsWith("u_")) peerId else ContactHelper.getUidByUinAsync(peerId.toLong())),
|
uid = LongMsgUid(if (peerId.startsWith("u_")) peerId else ContactHelper.getUidByUinAsync(peerId.toLong())),
|
||||||
payload = DeflateTools.gzip(payload.toByteArray())
|
payload = DeflateTools.gzip(payload.toByteArray())
|
||||||
)
|
)
|
||||||
|
|
||||||
MsgConstant.KCHATTYPEGROUP -> SendLongMsgInfo(
|
MsgConstant.KCHATTYPEGROUP -> SendLongMsgInfo(
|
||||||
type = 3,
|
type = 3,
|
||||||
uid = LongMsgUid(fromId),
|
uid = LongMsgUid(fromId),
|
||||||
groupUin = fromId.toULong(),
|
groupUin = fromId.toULong(),
|
||||||
payload = DeflateTools.gzip(payload.toByteArray())
|
payload = DeflateTools.gzip(payload.toByteArray())
|
||||||
)
|
)
|
||||||
|
|
||||||
else -> throw UnsupportedOperationException("Unsupported chatType: $chatType")
|
else -> throw UnsupportedOperationException("Unsupported chatType: $chatType")
|
||||||
},
|
},
|
||||||
setting = LongMsgSettings(
|
setting = LongMsgSettings(
|
||||||
@ -208,7 +216,8 @@ internal object ForwardMessageHelper: QQInterfaces() {
|
|||||||
)
|
)
|
||||||
).toByteArray()
|
).toByteArray()
|
||||||
|
|
||||||
val fromServiceMsg = sendBufferAW("trpc.group.long_msg_interface.MsgService.SsoSendLongMsg", true, req, timeout = 60.seconds)
|
val fromServiceMsg =
|
||||||
|
sendBufferAW("trpc.group.long_msg_interface.MsgService.SsoSendLongMsg", true, req, timeout = 60.seconds)
|
||||||
?: return Result.failure(Exception("unable to upload multi message, response timeout"))
|
?: return Result.failure(Exception("unable to upload multi message, response timeout"))
|
||||||
val rsp = runCatching {
|
val rsp = runCatching {
|
||||||
fromServiceMsg.wupBuffer.slice(4).decodeProtobuf<LongMsgRsp>()
|
fromServiceMsg.wupBuffer.slice(4).decodeProtobuf<LongMsgRsp>()
|
||||||
@ -217,11 +226,11 @@ internal object ForwardMessageHelper: QQInterfaces() {
|
|||||||
}
|
}
|
||||||
val resId = rsp.sendResult?.resId ?: return Result.failure(Exception("unable to upload multi message"))
|
val resId = rsp.sendResult?.resId ?: return Result.failure(Exception("unable to upload multi message"))
|
||||||
|
|
||||||
return Result.success(forwardElement {
|
return Result.success(ForwardElement.newBuilder().apply {
|
||||||
this.id = resId
|
this.id = resId
|
||||||
this.summary = summary
|
this.summary = summary
|
||||||
this.uniseq = UUID.randomUUID().toString()
|
this.uniseq = UUID.randomUUID().toString()
|
||||||
this.description = desc.slice(0..if (i < 3) i else 3).joinToString("\n")
|
this.description = desc.slice(0..if (i < 3) i else 3).joinToString("\n")
|
||||||
})
|
}.build())
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -5,27 +5,7 @@ import com.tencent.qqnt.kernel.nativeinterface.MsgConstant
|
|||||||
import com.tencent.qqnt.kernel.nativeinterface.MsgElement
|
import com.tencent.qqnt.kernel.nativeinterface.MsgElement
|
||||||
import com.tencent.qqnt.kernel.nativeinterface.MsgRecord
|
import com.tencent.qqnt.kernel.nativeinterface.MsgRecord
|
||||||
import com.tencent.qqnt.msg.api.IMsgService
|
import com.tencent.qqnt.msg.api.IMsgService
|
||||||
import io.kritor.event.Element
|
import io.kritor.message.*
|
||||||
import io.kritor.event.ImageType
|
|
||||||
import io.kritor.event.Scene
|
|
||||||
import io.kritor.event.atElement
|
|
||||||
import io.kritor.event.basketballElement
|
|
||||||
import io.kritor.event.buttonAction
|
|
||||||
import io.kritor.event.buttonActionPermission
|
|
||||||
import io.kritor.event.buttonRender
|
|
||||||
import io.kritor.event.contactElement
|
|
||||||
import io.kritor.event.diceElement
|
|
||||||
import io.kritor.event.faceElement
|
|
||||||
import io.kritor.event.forwardElement
|
|
||||||
import io.kritor.event.imageElement
|
|
||||||
import io.kritor.event.jsonElement
|
|
||||||
import io.kritor.event.locationElement
|
|
||||||
import io.kritor.event.pokeElement
|
|
||||||
import io.kritor.event.replyElement
|
|
||||||
import io.kritor.event.rpsElement
|
|
||||||
import io.kritor.event.textElement
|
|
||||||
import io.kritor.event.videoElement
|
|
||||||
import io.kritor.event.voiceElement
|
|
||||||
import kotlinx.coroutines.suspendCancellableCoroutine
|
import kotlinx.coroutines.suspendCancellableCoroutine
|
||||||
import kotlinx.coroutines.withTimeoutOrNull
|
import kotlinx.coroutines.withTimeoutOrNull
|
||||||
import moe.fuqiuluo.shamrock.helper.ActionMsgException
|
import moe.fuqiuluo.shamrock.helper.ActionMsgException
|
||||||
@ -75,12 +55,12 @@ private object MsgConvertor {
|
|||||||
val text = element.textElement
|
val text = element.textElement
|
||||||
val elem = Element.newBuilder()
|
val elem = Element.newBuilder()
|
||||||
if (text.atType != MsgConstant.ATTYPEUNKNOWN) {
|
if (text.atType != MsgConstant.ATTYPEUNKNOWN) {
|
||||||
elem.setAt(atElement {
|
elem.setAt(AtElement.newBuilder().apply {
|
||||||
this.uid = text.atNtUid
|
this.uid = text.atNtUid
|
||||||
this.uin = ContactHelper.getUinByUidAsync(text.atNtUid).toLong()
|
this.uin = ContactHelper.getUinByUidAsync(text.atNtUid).toLong()
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
elem.setText(textElement {
|
elem.setText(TextElement.newBuilder().apply {
|
||||||
this.text = text.content
|
this.text = text.content
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -91,28 +71,32 @@ private object MsgConvertor {
|
|||||||
val face = element.faceElement
|
val face = element.faceElement
|
||||||
val elem = Element.newBuilder()
|
val elem = Element.newBuilder()
|
||||||
if (face.faceType == 5) {
|
if (face.faceType == 5) {
|
||||||
elem.setPoke(pokeElement {
|
elem.setPoke(PokeElement.newBuilder().apply {
|
||||||
this.id = face.vaspokeId
|
this.id = face.vaspokeId
|
||||||
this.type = face.pokeType
|
this.type = face.pokeType
|
||||||
this.strength = face.pokeStrength
|
this.strength = face.pokeStrength
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
when (face.faceIndex) {
|
when (face.faceIndex) {
|
||||||
114 -> elem.setBasketball(basketballElement {
|
114 -> elem.setBasketball(BasketballElement.newBuilder().apply {
|
||||||
this.id = face.resultId.ifNullOrEmpty { "0" }?.toInt() ?: 0
|
this.id = face.resultId.ifNullOrEmpty { "0" }?.toInt() ?: 0
|
||||||
})
|
})
|
||||||
358 -> elem.setDice(diceElement {
|
|
||||||
|
358 -> elem.setDice(DiceElement.newBuilder().apply {
|
||||||
this.id = face.resultId.ifNullOrEmpty { "0" }?.toInt() ?: 0
|
this.id = face.resultId.ifNullOrEmpty { "0" }?.toInt() ?: 0
|
||||||
})
|
})
|
||||||
359 -> elem.setRps(rpsElement {
|
|
||||||
|
359 -> elem.setRps(RpsElement.newBuilder().apply {
|
||||||
this.id = face.resultId.ifNullOrEmpty { "0" }?.toInt() ?: 0
|
this.id = face.resultId.ifNullOrEmpty { "0" }?.toInt() ?: 0
|
||||||
})
|
})
|
||||||
394 -> elem.setFace(faceElement {
|
|
||||||
|
394 -> elem.setFace(FaceElement.newBuilder().apply {
|
||||||
this.id = face.faceIndex
|
this.id = face.faceIndex
|
||||||
this.isBig = face.faceType == 3
|
this.isBig = face.faceType == 3
|
||||||
this.result = face.resultId.ifNullOrEmpty { "1" }?.toInt() ?: 1
|
this.result = face.resultId.ifNullOrEmpty { "1" }?.toInt() ?: 1
|
||||||
})
|
})
|
||||||
else -> elem.setFace(faceElement {
|
|
||||||
|
else -> elem.setFace(FaceElement.newBuilder().apply {
|
||||||
this.id = face.faceIndex
|
this.id = face.faceIndex
|
||||||
this.isBig = face.faceType == 3
|
this.isBig = face.faceType == 3
|
||||||
})
|
})
|
||||||
@ -150,7 +134,7 @@ private object MsgConvertor {
|
|||||||
LogCenter.log({ "receive image: $image" }, Level.DEBUG)
|
LogCenter.log({ "receive image: $image" }, Level.DEBUG)
|
||||||
|
|
||||||
val elem = Element.newBuilder()
|
val elem = Element.newBuilder()
|
||||||
elem.setImage(imageElement {
|
elem.setImage(ImageElement.newBuilder().apply {
|
||||||
this.file = md5
|
this.file = md5
|
||||||
this.url = when (record.chatType) {
|
this.url = when (record.chatType) {
|
||||||
MsgConstant.KCHATTYPEDISC, MsgConstant.KCHATTYPEGROUP -> RichProtoSvc.getGroupPicDownUrl(
|
MsgConstant.KCHATTYPEDISC, MsgConstant.KCHATTYPEGROUP -> RichProtoSvc.getGroupPicDownUrl(
|
||||||
@ -190,7 +174,8 @@ private object MsgConvertor {
|
|||||||
|
|
||||||
else -> throw UnsupportedOperationException("Not supported chat type: ${record.chatType}")
|
else -> throw UnsupportedOperationException("Not supported chat type: ${record.chatType}")
|
||||||
}
|
}
|
||||||
this.type = if (image.isFlashPic == true) ImageType.FLASH else if (image.original) ImageType.ORIGIN else ImageType.COMMON
|
this.type =
|
||||||
|
if (image.isFlashPic == true) ImageType.FLASH else if (image.original) ImageType.ORIGIN else ImageType.COMMON
|
||||||
this.subType = image.picSubType
|
this.subType = image.picSubType
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -205,10 +190,14 @@ private object MsgConvertor {
|
|||||||
ptt.fileName.substring(5)
|
ptt.fileName.substring(5)
|
||||||
else ptt.md5HexStr
|
else ptt.md5HexStr
|
||||||
|
|
||||||
elem.setVoice(voiceElement {
|
elem.setVoice(VoiceElement.newBuilder().apply {
|
||||||
this.url = when (record.chatType) {
|
this.url = when (record.chatType) {
|
||||||
MsgConstant.KCHATTYPEC2C -> RichProtoSvc.getC2CPttDownUrl("0", ptt.fileUuid)
|
MsgConstant.KCHATTYPEC2C -> RichProtoSvc.getC2CPttDownUrl("0", ptt.fileUuid)
|
||||||
MsgConstant.KCHATTYPEGROUP, MsgConstant.KCHATTYPEGUILD -> RichProtoSvc.getGroupPttDownUrl("0", md5.hex2ByteArray(), ptt.fileUuid)
|
MsgConstant.KCHATTYPEGROUP, MsgConstant.KCHATTYPEGUILD -> RichProtoSvc.getGroupPttDownUrl(
|
||||||
|
"0",
|
||||||
|
md5.hex2ByteArray(),
|
||||||
|
ptt.fileUuid
|
||||||
|
)
|
||||||
|
|
||||||
else -> throw UnsupportedOperationException("Not supported chat type: ${record.chatType}")
|
else -> throw UnsupportedOperationException("Not supported chat type: ${record.chatType}")
|
||||||
}
|
}
|
||||||
@ -229,7 +218,7 @@ private object MsgConvertor {
|
|||||||
it[it.size - 2].hex2ByteArray()
|
it[it.size - 2].hex2ByteArray()
|
||||||
}
|
}
|
||||||
} else video.fileName.split(".")[0].hex2ByteArray()
|
} else video.fileName.split(".")[0].hex2ByteArray()
|
||||||
elem.setVideo(videoElement {
|
elem.setVideo(VideoElement.newBuilder().apply {
|
||||||
this.file = md5.toHexString()
|
this.file = md5.toHexString()
|
||||||
this.url = when (record.chatType) {
|
this.url = when (record.chatType) {
|
||||||
MsgConstant.KCHATTYPEGROUP -> RichProtoSvc.getGroupVideoDownUrl("0", md5, video.fileUuid)
|
MsgConstant.KCHATTYPEGROUP -> RichProtoSvc.getGroupVideoDownUrl("0", md5, video.fileUuid)
|
||||||
@ -244,7 +233,7 @@ private object MsgConvertor {
|
|||||||
suspend fun convertMarketFace(record: MsgRecord, element: MsgElement): Result<Element> {
|
suspend fun convertMarketFace(record: MsgRecord, element: MsgElement): Result<Element> {
|
||||||
val marketFace = element.marketFaceElement
|
val marketFace = element.marketFaceElement
|
||||||
val elem = Element.newBuilder()
|
val elem = Element.newBuilder()
|
||||||
elem.setMarketFace(io.kritor.event.marketFaceElement {
|
elem.setMarketFace(MarketFaceElement.newBuilder().apply {
|
||||||
this.id = marketFace.emojiId.lowercase()
|
this.id = marketFace.emojiId.lowercase()
|
||||||
})
|
})
|
||||||
return Result.success(elem.build())
|
return Result.success(elem.build())
|
||||||
@ -256,8 +245,8 @@ private object MsgConvertor {
|
|||||||
when (data["app"].asString) {
|
when (data["app"].asString) {
|
||||||
"com.tencent.multimsg" -> {
|
"com.tencent.multimsg" -> {
|
||||||
val info = data["meta"].asJsonObject["detail"].asJsonObject
|
val info = data["meta"].asJsonObject["detail"].asJsonObject
|
||||||
elem.setForward(forwardElement {
|
elem.setForward(ForwardElement.newBuilder().apply {
|
||||||
this.id = info["resid"].asString
|
this.resId = info["resid"].asString
|
||||||
this.uniseq = info["uniseq"].asString
|
this.uniseq = info["uniseq"].asString
|
||||||
this.summary = info["summary"].asString
|
this.summary = info["summary"].asString
|
||||||
this.description = info["news"].asJsonArray.joinToString("\n") {
|
this.description = info["news"].asJsonArray.joinToString("\n") {
|
||||||
@ -268,7 +257,7 @@ private object MsgConvertor {
|
|||||||
|
|
||||||
"com.tencent.troopsharecard" -> {
|
"com.tencent.troopsharecard" -> {
|
||||||
val info = data["meta"].asJsonObject["contact"].asJsonObject
|
val info = data["meta"].asJsonObject["contact"].asJsonObject
|
||||||
elem.setContact(contactElement {
|
elem.setContact(ContactElement.newBuilder().apply {
|
||||||
this.scene = Scene.GROUP
|
this.scene = Scene.GROUP
|
||||||
this.peer = info["jumpUrl"].asString.split("group_code=")[1]
|
this.peer = info["jumpUrl"].asString.split("group_code=")[1]
|
||||||
})
|
})
|
||||||
@ -276,7 +265,7 @@ private object MsgConvertor {
|
|||||||
|
|
||||||
"com.tencent.contact.lua" -> {
|
"com.tencent.contact.lua" -> {
|
||||||
val info = data["meta"].asJsonObject["contact"].asJsonObject
|
val info = data["meta"].asJsonObject["contact"].asJsonObject
|
||||||
elem.setContact(contactElement {
|
elem.setContact(ContactElement.newBuilder().apply {
|
||||||
this.scene = Scene.FRIEND
|
this.scene = Scene.FRIEND
|
||||||
this.peer = info["jumpUrl"].asString.split("uin=")[1]
|
this.peer = info["jumpUrl"].asString.split("uin=")[1]
|
||||||
})
|
})
|
||||||
@ -284,7 +273,7 @@ private object MsgConvertor {
|
|||||||
|
|
||||||
"com.tencent.map" -> {
|
"com.tencent.map" -> {
|
||||||
val info = data["meta"].asJsonObject["Location.Search"].asJsonObject
|
val info = data["meta"].asJsonObject["Location.Search"].asJsonObject
|
||||||
elem.setLocation(locationElement {
|
elem.setLocation(LocationElement.newBuilder().apply {
|
||||||
this.lat = info["lat"].asString.toFloat()
|
this.lat = info["lat"].asString.toFloat()
|
||||||
this.lon = info["lng"].asString.toFloat()
|
this.lon = info["lng"].asString.toFloat()
|
||||||
this.address = info["address"].asString
|
this.address = info["address"].asString
|
||||||
@ -292,7 +281,7 @@ private object MsgConvertor {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
else -> elem.setJson(jsonElement {
|
else -> elem.setJson(JsonElement.newBuilder().apply {
|
||||||
this.json = data.toString()
|
this.json = data.toString()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -302,12 +291,13 @@ private object MsgConvertor {
|
|||||||
suspend fun convertReply(record: MsgRecord, element: MsgElement): Result<Element> {
|
suspend fun convertReply(record: MsgRecord, element: MsgElement): Result<Element> {
|
||||||
val reply = element.replyElement
|
val reply = element.replyElement
|
||||||
val elem = Element.newBuilder()
|
val elem = Element.newBuilder()
|
||||||
elem.setReply(replyElement {
|
elem.setReply(ReplyElement.newBuilder().apply {
|
||||||
val msgSeq = reply.replayMsgSeq
|
val msgSeq = reply.replayMsgSeq
|
||||||
val contact = MessageHelper.generateContact(record)
|
val contact = MessageHelper.generateContact(record)
|
||||||
val sourceRecords = withTimeoutOrNull(3000) {
|
val sourceRecords = withTimeoutOrNull(3000) {
|
||||||
suspendCancellableCoroutine {
|
suspendCancellableCoroutine {
|
||||||
QRoute.api(IMsgService::class.java).getMsgsBySeqAndCount(contact, msgSeq, 1, true) { _, _, records ->
|
QRoute.api(IMsgService::class.java)
|
||||||
|
.getMsgsBySeqAndCount(contact, msgSeq, 1, true) { _, _, records ->
|
||||||
it.resume(records)
|
it.resume(records)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -332,11 +322,17 @@ private object MsgConvertor {
|
|||||||
val fileSubId = fileMsg.fileSubId ?: ""
|
val fileSubId = fileMsg.fileSubId ?: ""
|
||||||
val url = when (record.chatType) {
|
val url = when (record.chatType) {
|
||||||
MsgConstant.KCHATTYPEC2C -> RichProtoSvc.getC2CFileDownUrl(fileId, fileSubId)
|
MsgConstant.KCHATTYPEC2C -> RichProtoSvc.getC2CFileDownUrl(fileId, fileSubId)
|
||||||
MsgConstant.KCHATTYPEGUILD -> RichProtoSvc.getGuildFileDownUrl(record.guildId, record.channelId, fileId, bizId)
|
MsgConstant.KCHATTYPEGUILD -> RichProtoSvc.getGuildFileDownUrl(
|
||||||
|
record.guildId,
|
||||||
|
record.channelId,
|
||||||
|
fileId,
|
||||||
|
bizId
|
||||||
|
)
|
||||||
|
|
||||||
else -> RichProtoSvc.getGroupFileDownUrl(record.peerUin, fileId, bizId)
|
else -> RichProtoSvc.getGroupFileDownUrl(record.peerUin, fileId, bizId)
|
||||||
}
|
}
|
||||||
val elem = Element.newBuilder()
|
val elem = Element.newBuilder()
|
||||||
elem.setFile(io.kritor.event.fileElement {
|
elem.setFile(FileElement.newBuilder().apply {
|
||||||
this.name = fileName
|
this.name = fileName
|
||||||
this.size = fileSize
|
this.size = fileSize
|
||||||
this.url = url
|
this.url = url
|
||||||
@ -351,7 +347,7 @@ private object MsgConvertor {
|
|||||||
suspend fun convertMarkdown(record: MsgRecord, element: MsgElement): Result<Element> {
|
suspend fun convertMarkdown(record: MsgRecord, element: MsgElement): Result<Element> {
|
||||||
val markdown = element.markdownElement
|
val markdown = element.markdownElement
|
||||||
val elem = Element.newBuilder()
|
val elem = Element.newBuilder()
|
||||||
elem.setMarkdown(io.kritor.event.markdownElement {
|
elem.setMarkdown(MarkdownElement.newBuilder().apply {
|
||||||
this.markdown = markdown.content
|
this.markdown = markdown.content
|
||||||
})
|
})
|
||||||
return Result.success(elem.build())
|
return Result.success(elem.build())
|
||||||
@ -360,7 +356,7 @@ private object MsgConvertor {
|
|||||||
suspend fun convertBubbleFace(record: MsgRecord, element: MsgElement): Result<Element> {
|
suspend fun convertBubbleFace(record: MsgRecord, element: MsgElement): Result<Element> {
|
||||||
val bubbleFace = element.faceBubbleElement
|
val bubbleFace = element.faceBubbleElement
|
||||||
val elem = Element.newBuilder()
|
val elem = Element.newBuilder()
|
||||||
elem.setBubbleFace(io.kritor.event.bubbleFaceElement {
|
elem.setBubbleFace(BubbleFaceElement.newBuilder().apply {
|
||||||
this.id = bubbleFace.yellowFaceInfo.index
|
this.id = bubbleFace.yellowFaceInfo.index
|
||||||
this.count = bubbleFace.faceCount ?: 1
|
this.count = bubbleFace.faceCount ?: 1
|
||||||
})
|
})
|
||||||
@ -370,34 +366,34 @@ private object MsgConvertor {
|
|||||||
suspend fun convertInlineKeyboard(record: MsgRecord, element: MsgElement): Result<Element> {
|
suspend fun convertInlineKeyboard(record: MsgRecord, element: MsgElement): Result<Element> {
|
||||||
val inlineKeyboard = element.inlineKeyboardElement
|
val inlineKeyboard = element.inlineKeyboardElement
|
||||||
val elem = Element.newBuilder()
|
val elem = Element.newBuilder()
|
||||||
elem.setButton(io.kritor.event.buttonElement {
|
elem.setButton(ButtonElement.newBuilder().apply {
|
||||||
inlineKeyboard.rows.forEach { row ->
|
inlineKeyboard.rows.forEach { row ->
|
||||||
this.rows.add(io.kritor.event.row {
|
this.addRows(ButtonRow.newBuilder().apply {
|
||||||
row.buttons.forEach buttonsLoop@{ button ->
|
row.buttons.forEach buttonsLoop@{ button ->
|
||||||
if (button == null) return@buttonsLoop
|
if (button == null) return@buttonsLoop
|
||||||
this.buttons.add(io.kritor.event.button {
|
this.addButtons(Button.newBuilder().apply {
|
||||||
this.id = button.id
|
this.id = button.id
|
||||||
this.action = buttonAction {
|
this.action = ButtonAction.newBuilder().apply {
|
||||||
this.type = button.type
|
this.type = button.type
|
||||||
this.permission = buttonActionPermission {
|
this.permission = ButtonActionPermission.newBuilder().apply {
|
||||||
this.type = button.permissionType
|
this.type = button.permissionType
|
||||||
button.specifyRoleIds?.let {
|
button.specifyRoleIds?.let {
|
||||||
this.roleIds.addAll(it)
|
this.addAllRoleIds(it)
|
||||||
}
|
}
|
||||||
button.specifyTinyids?.let {
|
button.specifyTinyids?.let {
|
||||||
this.userIds.addAll(it)
|
this.addAllUserIds(it)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}.build()
|
||||||
this.unsupportedTips = button.unsupportTips ?: ""
|
this.unsupportedTips = button.unsupportTips ?: ""
|
||||||
this.data = button.data ?: ""
|
this.data = button.data ?: ""
|
||||||
this.reply = button.isReply
|
this.reply = button.isReply
|
||||||
this.enter = button.enter
|
this.enter = button.enter
|
||||||
}
|
}.build()
|
||||||
this.renderData = buttonRender {
|
this.renderData = ButtonRender.newBuilder().apply {
|
||||||
this.label = button.label ?: ""
|
this.label = button.label ?: ""
|
||||||
this.visitedLabel = button.visitedLabel ?: ""
|
this.visitedLabel = button.visitedLabel ?: ""
|
||||||
this.style = button.style
|
this.style = button.style
|
||||||
}
|
}.build()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -1,24 +1,10 @@
|
|||||||
@file:OptIn(ExperimentalUnsignedTypes::class)
|
@file:OptIn(ExperimentalUnsignedTypes::class)
|
||||||
|
|
||||||
package qq.service.msg
|
package qq.service.msg
|
||||||
|
|
||||||
import com.tencent.qqnt.kernel.nativeinterface.Contact
|
import com.tencent.qqnt.kernel.nativeinterface.Contact
|
||||||
import com.tencent.qqnt.kernel.nativeinterface.MsgConstant
|
import com.tencent.qqnt.kernel.nativeinterface.MsgConstant
|
||||||
import io.kritor.message.Element
|
import io.kritor.message.*
|
||||||
import io.kritor.message.ElementType
|
|
||||||
import io.kritor.message.ImageType
|
|
||||||
import io.kritor.message.Scene
|
|
||||||
import io.kritor.message.atElement
|
|
||||||
import io.kritor.message.buttonActionPermission
|
|
||||||
import io.kritor.message.buttonElement
|
|
||||||
import io.kritor.message.contactElement
|
|
||||||
import io.kritor.message.faceElement
|
|
||||||
import io.kritor.message.forwardElement
|
|
||||||
import io.kritor.message.imageElement
|
|
||||||
import io.kritor.message.jsonElement
|
|
||||||
import io.kritor.message.locationElement
|
|
||||||
import io.kritor.message.markdownElement
|
|
||||||
import io.kritor.message.replyElement
|
|
||||||
import io.kritor.message.textElement
|
|
||||||
import kotlinx.io.core.ByteReadPacket
|
import kotlinx.io.core.ByteReadPacket
|
||||||
import kotlinx.io.core.discardExact
|
import kotlinx.io.core.discardExact
|
||||||
import kotlinx.io.core.readUInt
|
import kotlinx.io.core.readUInt
|
||||||
@ -48,142 +34,151 @@ suspend fun List<Elem>.toKritorResponseMessages(contact: Contact): ArrayList<Ele
|
|||||||
val at = ByteReadPacket(text.attr6Buf!!)
|
val at = ByteReadPacket(text.attr6Buf!!)
|
||||||
at.discardExact(7)
|
at.discardExact(7)
|
||||||
val uin = at.readUInt()
|
val uin = at.readUInt()
|
||||||
kritorMessages.add(io.kritor.message.element {
|
kritorMessages.add(Element.newBuilder().apply {
|
||||||
this.type = ElementType.AT
|
this.type = ElementType.AT
|
||||||
this.at = atElement {
|
this.at = AtElement.newBuilder().apply {
|
||||||
this.uin = uin.toLong()
|
this.uin = uin.toLong()
|
||||||
}
|
}.build()
|
||||||
})
|
}.build())
|
||||||
} else {
|
} else {
|
||||||
kritorMessages.add(io.kritor.message.element {
|
kritorMessages.add(Element.newBuilder().apply {
|
||||||
this.type = ElementType.TEXT
|
this.type = ElementType.TEXT
|
||||||
this.text = textElement {
|
this.text = TextElement.newBuilder().apply {
|
||||||
this.text = text.str ?: ""
|
this.text = text.str ?: ""
|
||||||
}
|
}.build()
|
||||||
})
|
}.build())
|
||||||
}
|
}
|
||||||
} else if (element.face != null) {
|
} else if (element.face != null) {
|
||||||
kritorMessages.add(io.kritor.message.element {
|
kritorMessages.add(Element.newBuilder().apply {
|
||||||
this.type = ElementType.FACE
|
this.type = ElementType.FACE
|
||||||
this.face = faceElement {
|
this.face = FaceElement.newBuilder().apply {
|
||||||
this.id = element.face!!.index ?: 0
|
this.id = element.face!!.index ?: 0
|
||||||
}
|
}.build()
|
||||||
})
|
}.build())
|
||||||
} else if (element.customFace != null) {
|
} else if (element.customFace != null) {
|
||||||
val customFace = element.customFace!!
|
val customFace = element.customFace!!
|
||||||
val md5 = customFace.md5.toHexString()
|
val md5 = customFace.md5.toHexString()
|
||||||
val origUrl = customFace.origUrl!!
|
val origUrl = customFace.origUrl!!
|
||||||
kritorMessages.add(io.kritor.message.element {
|
kritorMessages.add(Element.newBuilder().apply {
|
||||||
this.type = ElementType.IMAGE
|
this.type = ElementType.IMAGE
|
||||||
this.image = imageElement {
|
this.image = ImageElement.newBuilder().apply {
|
||||||
this.fileName = md5
|
this.fileName = md5
|
||||||
this.type = if (customFace.origin == true) ImageType.ORIGIN else ImageType.COMMON
|
this.type = if (customFace.origin == true) ImageType.ORIGIN else ImageType.COMMON
|
||||||
this.url = when (contact.chatType) {
|
this.url = when (contact.chatType) {
|
||||||
MsgConstant.KCHATTYPEDISC, MsgConstant.KCHATTYPEGROUP -> RichProtoSvc.getGroupPicDownUrl(origUrl, md5)
|
MsgConstant.KCHATTYPEDISC, MsgConstant.KCHATTYPEGROUP -> RichProtoSvc.getGroupPicDownUrl(
|
||||||
|
origUrl,
|
||||||
|
md5
|
||||||
|
)
|
||||||
|
|
||||||
MsgConstant.KCHATTYPEC2C -> RichProtoSvc.getC2CPicDownUrl(origUrl, md5)
|
MsgConstant.KCHATTYPEC2C -> RichProtoSvc.getC2CPicDownUrl(origUrl, md5)
|
||||||
MsgConstant.KCHATTYPEGUILD -> RichProtoSvc.getGuildPicDownUrl(origUrl, md5)
|
MsgConstant.KCHATTYPEGUILD -> RichProtoSvc.getGuildPicDownUrl(origUrl, md5)
|
||||||
else -> throw UnsupportedOperationException("Not supported chat type: $contact")
|
else -> throw UnsupportedOperationException("Not supported chat type: $contact")
|
||||||
}
|
}
|
||||||
}
|
}.build()
|
||||||
})
|
}.build())
|
||||||
} else if (element.notOnlineImage != null) {
|
} else if (element.notOnlineImage != null) {
|
||||||
require(element.notOnlineImage != null)
|
|
||||||
val md5 = element.notOnlineImage!!.picMd5.toHexString()
|
val md5 = element.notOnlineImage!!.picMd5.toHexString()
|
||||||
val origUrl = element.notOnlineImage!!.origUrl!!
|
val origUrl = element.notOnlineImage!!.origUrl!!
|
||||||
kritorMessages.add(io.kritor.message.element {
|
kritorMessages.add(Element.newBuilder().apply {
|
||||||
this.type = ElementType.IMAGE
|
this.type = ElementType.IMAGE
|
||||||
this.image = imageElement {
|
this.image = ImageElement.newBuilder().apply {
|
||||||
this.fileName = md5
|
this.fileName = md5
|
||||||
this.type = if (element.notOnlineImage?.original == true) ImageType.ORIGIN else ImageType.COMMON
|
this.type = if (element.notOnlineImage?.original == true) ImageType.ORIGIN else ImageType.COMMON
|
||||||
this.url = when (contact.chatType) {
|
this.url = when (contact.chatType) {
|
||||||
MsgConstant.KCHATTYPEDISC, MsgConstant.KCHATTYPEGROUP -> RichProtoSvc.getGroupPicDownUrl(origUrl, md5)
|
MsgConstant.KCHATTYPEDISC, MsgConstant.KCHATTYPEGROUP -> RichProtoSvc.getGroupPicDownUrl(
|
||||||
|
origUrl,
|
||||||
|
md5
|
||||||
|
)
|
||||||
|
|
||||||
MsgConstant.KCHATTYPEC2C -> RichProtoSvc.getC2CPicDownUrl(origUrl, md5)
|
MsgConstant.KCHATTYPEC2C -> RichProtoSvc.getC2CPicDownUrl(origUrl, md5)
|
||||||
MsgConstant.KCHATTYPEGUILD -> RichProtoSvc.getGuildPicDownUrl(origUrl, md5)
|
MsgConstant.KCHATTYPEGUILD -> RichProtoSvc.getGuildPicDownUrl(origUrl, md5)
|
||||||
else -> throw UnsupportedOperationException("Not supported chat type: $contact")
|
else -> throw UnsupportedOperationException("Not supported chat type: $contact")
|
||||||
}
|
}
|
||||||
}
|
}.build()
|
||||||
})
|
}.build())
|
||||||
} else if (element.generalFlags != null) {
|
} else if (element.generalFlags != null) {
|
||||||
val generalFlags = element.generalFlags!!
|
// val generalFlags = element.generalFlags!!
|
||||||
if (generalFlags.longTextFlag == 1u) {
|
// if (generalFlags.longTextFlag == 1u) {
|
||||||
kritorMessages.add(io.kritor.message.element {
|
// kritorMessages.add(Element.newBuilder().apply {
|
||||||
this.type = ElementType.FORWARD
|
// this.type = ElementType.FORWARD
|
||||||
this.forward = forwardElement {
|
// this.forward = forwardElement {
|
||||||
this.id = generalFlags.longTextResid ?: ""
|
// this.id = generalFlags.longTextResid ?: ""
|
||||||
}
|
// }
|
||||||
})
|
// })
|
||||||
}
|
// }
|
||||||
} else if (element.srcMsg != null) {
|
} else if (element.srcMsg != null) {
|
||||||
val srcMsg = element.srcMsg!!
|
val srcMsg = element.srcMsg!!
|
||||||
val msgId = srcMsg.pbReserve?.msgRand?.toLong() ?: 0
|
val msgId = srcMsg.pbReserve?.msgRand?.toLong() ?: 0
|
||||||
kritorMessages.add(io.kritor.message.element {
|
kritorMessages.add(Element.newBuilder().apply {
|
||||||
this.type = ElementType.REPLY
|
this.type = ElementType.REPLY
|
||||||
this.reply = replyElement {
|
this.reply = ReplyElement.newBuilder().apply {
|
||||||
this.messageId = msgId
|
this.messageId = msgId
|
||||||
}
|
}.build()
|
||||||
})
|
}.build())
|
||||||
} else if (element.lightApp != null) {
|
} else if (element.lightApp != null) {
|
||||||
val data = element.lightApp!!.data!!
|
val data = element.lightApp!!.data!!
|
||||||
val jsonStr = (if (data[0].toInt() == 1) DeflateTools.uncompress(data.slice(1)) else data.slice(1)).decodeToString()
|
val jsonStr =
|
||||||
|
(if (data[0].toInt() == 1) DeflateTools.uncompress(data.slice(1)) else data.slice(1)).decodeToString()
|
||||||
val json = jsonStr.asJsonObject
|
val json = jsonStr.asJsonObject
|
||||||
when (json["app"].asString) {
|
when (json["app"].asString) {
|
||||||
"com.tencent.multimsg" -> {
|
"com.tencent.multimsg" -> {
|
||||||
val info = json["meta"].asJsonObject["detail"].asJsonObject
|
val info = json["meta"].asJsonObject["detail"].asJsonObject
|
||||||
kritorMessages.add(io.kritor.message.element {
|
kritorMessages.add(Element.newBuilder().apply {
|
||||||
this.type = ElementType.FORWARD
|
this.type = ElementType.FORWARD
|
||||||
this.forward = forwardElement {
|
this.forward = ForwardElement.newBuilder().apply {
|
||||||
this.id = info["resid"].asString
|
this.resId = info["resid"].asString
|
||||||
this.uniseq = info["uniseq"].asString
|
this.uniseq = info["uniseq"].asString
|
||||||
this.summary = info["summary"].asString
|
this.summary = info["summary"].asString
|
||||||
this.description = info["news"].asJsonArray.joinToString("\n") {
|
this.description = info["news"].asJsonArray.joinToString("\n") {
|
||||||
it.asJsonObject["text"].asString
|
it.asJsonObject["text"].asString
|
||||||
}
|
}
|
||||||
}
|
}.build()
|
||||||
})
|
}.build())
|
||||||
}
|
}
|
||||||
|
|
||||||
"com.tencent.troopsharecard" -> {
|
"com.tencent.troopsharecard" -> {
|
||||||
val info = json["meta"].asJsonObject["contact"].asJsonObject
|
val info = json["meta"].asJsonObject["contact"].asJsonObject
|
||||||
kritorMessages.add(io.kritor.message.element {
|
kritorMessages.add(Element.newBuilder().apply {
|
||||||
this.type = ElementType.CONTACT
|
this.type = ElementType.CONTACT
|
||||||
this.contact = contactElement {
|
this.contact = ContactElement.newBuilder().apply {
|
||||||
this.scene = Scene.GROUP
|
this.scene = Scene.GROUP
|
||||||
this.peer = info["jumpUrl"].asString.split("group_code=")[1]
|
this.peer = info["jumpUrl"].asString.split("group_code=")[1]
|
||||||
}
|
}.build()
|
||||||
})
|
}.build())
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
"com.tencent.contact.lua" -> {
|
"com.tencent.contact.lua" -> {
|
||||||
val info = json["meta"].asJsonObject["contact"].asJsonObject
|
val info = json["meta"].asJsonObject["contact"].asJsonObject
|
||||||
kritorMessages.add(io.kritor.message.element {
|
kritorMessages.add(Element.newBuilder().apply {
|
||||||
this.type = ElementType.CONTACT
|
this.type = ElementType.CONTACT
|
||||||
this.contact = contactElement {
|
this.contact = ContactElement.newBuilder().apply {
|
||||||
this.scene = Scene.FRIEND
|
this.scene = Scene.FRIEND
|
||||||
this.peer = info["jumpUrl"].asString.split("uin=")[1]
|
this.peer = info["jumpUrl"].asString.split("uin=")[1]
|
||||||
}
|
}.build()
|
||||||
})
|
}.build())
|
||||||
}
|
}
|
||||||
|
|
||||||
"com.tencent.map" -> {
|
"com.tencent.map" -> {
|
||||||
val info = json["meta"].asJsonObject["Location.Search"].asJsonObject
|
val info = json["meta"].asJsonObject["Location.Search"].asJsonObject
|
||||||
kritorMessages.add(io.kritor.message.element {
|
kritorMessages.add(Element.newBuilder().apply {
|
||||||
this.type = ElementType.LOCATION
|
this.type = ElementType.LOCATION
|
||||||
this.location = locationElement {
|
this.location = LocationElement.newBuilder().apply {
|
||||||
this.lat = info["lat"].asString.toFloat()
|
this.lat = info["lat"].asString.toFloat()
|
||||||
this.lon = info["lng"].asString.toFloat()
|
this.lon = info["lng"].asString.toFloat()
|
||||||
this.address = info["address"].asString
|
this.address = info["address"].asString
|
||||||
this.title = info["name"].asString
|
this.title = info["name"].asString
|
||||||
|
}.build()
|
||||||
|
}.build())
|
||||||
}
|
}
|
||||||
})
|
|
||||||
}
|
|
||||||
else -> {
|
else -> {
|
||||||
kritorMessages.add(io.kritor.message.element {
|
kritorMessages.add(Element.newBuilder().apply {
|
||||||
this.type = ElementType.JSON
|
this.type = ElementType.JSON
|
||||||
this.json = jsonElement {
|
this.json = JsonElement.newBuilder().apply {
|
||||||
this.json = jsonStr
|
this.json = jsonStr
|
||||||
}
|
}.build()
|
||||||
})
|
}.build())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (element.commonElem != null) {
|
} else if (element.commonElem != null) {
|
||||||
@ -192,81 +187,78 @@ suspend fun List<Elem>.toKritorResponseMessages(contact: Contact): ArrayList<Ele
|
|||||||
37 -> {
|
37 -> {
|
||||||
val qFaceExtra = commonElem.elem!!.decodeProtobuf<QFaceExtra>()
|
val qFaceExtra = commonElem.elem!!.decodeProtobuf<QFaceExtra>()
|
||||||
when (qFaceExtra.faceId) {
|
when (qFaceExtra.faceId) {
|
||||||
358 -> kritorMessages.add(io.kritor.message.element {
|
358 -> kritorMessages.add(Element.newBuilder().apply {
|
||||||
this.type = ElementType.DICE
|
this.type = ElementType.DICE
|
||||||
this.dice = io.kritor.message.diceElement {
|
this.dice = DiceElement.newBuilder().apply {
|
||||||
this.id = qFaceExtra.result!!.toInt()
|
this.id = qFaceExtra.result!!.toInt()
|
||||||
}
|
}.build()
|
||||||
})
|
}.build())
|
||||||
|
|
||||||
359 -> kritorMessages.add(io.kritor.message.element {
|
359 -> kritorMessages.add(Element.newBuilder().apply {
|
||||||
this.type = ElementType.RPS
|
this.type = ElementType.RPS
|
||||||
this.rps = io.kritor.message.rpsElement {
|
this.rps = RpsElement.newBuilder().apply {
|
||||||
this.id = qFaceExtra.result!!.toInt()
|
this.id = qFaceExtra.result!!.toInt()
|
||||||
}
|
}.build()
|
||||||
})
|
}.build())
|
||||||
|
|
||||||
else -> kritorMessages.add(io.kritor.message.element {
|
else -> kritorMessages.add(Element.newBuilder().apply {
|
||||||
this.type = ElementType.FACE
|
this.type = ElementType.FACE
|
||||||
this.face = faceElement {
|
this.face = FaceElement.newBuilder().apply {
|
||||||
this.id = qFaceExtra.faceId ?: 0
|
this.id = qFaceExtra.faceId ?: 0
|
||||||
this.isBig = false
|
this.isBig = false
|
||||||
this.result = qFaceExtra.result?.toInt() ?: 0
|
this.result = qFaceExtra.result?.toInt() ?: 0
|
||||||
}
|
}.build()
|
||||||
})
|
}.build())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
45 -> {
|
45 -> {
|
||||||
val markdownExtra = commonElem.elem!!.decodeProtobuf<MarkdownExtra>()
|
val markdownExtra = commonElem.elem!!.decodeProtobuf<MarkdownExtra>()
|
||||||
kritorMessages.add(io.kritor.message.element {
|
kritorMessages.add(Element.newBuilder().apply {
|
||||||
this.type = ElementType.MARKDOWN
|
this.type = ElementType.MARKDOWN
|
||||||
this.markdown = markdownElement {
|
this.markdown = MarkdownElement.newBuilder().apply {
|
||||||
this.markdown = markdownExtra.content!!
|
this.markdown = markdownExtra.content!!
|
||||||
}
|
}.build()
|
||||||
})
|
}.build())
|
||||||
}
|
}
|
||||||
|
|
||||||
46 -> {
|
46 -> {
|
||||||
val buttonExtra = commonElem.elem!!.decodeProtobuf<ButtonExtra>()
|
val buttonExtra = commonElem.elem!!.decodeProtobuf<ButtonExtra>()
|
||||||
kritorMessages.add(io.kritor.message.element {
|
kritorMessages.add(
|
||||||
this.type = ElementType.BUTTON
|
Element.newBuilder().setButton(ButtonElement.newBuilder().apply {
|
||||||
this.button = buttonElement {
|
this.addAllRows(buttonExtra.field1!!.rows!!.map { row ->
|
||||||
buttonExtra.field1!!.rows?.forEach { row ->
|
ButtonRow.newBuilder().apply {
|
||||||
this.rows.add(io.kritor.message.row {
|
this.addAllButtons(row.buttons!!.map { button ->
|
||||||
row.buttons?.forEach { button ->
|
Button.newBuilder().apply {
|
||||||
this.buttons.add(io.kritor.message.button {
|
this.id = button.id
|
||||||
val renderData = button.renderData
|
this.renderData = ButtonRender.newBuilder().apply {
|
||||||
val action = button.action
|
this.label = button.renderData?.label ?: ""
|
||||||
val permission = action?.permission
|
this.visitedLabel = button.renderData?.visitedLabel ?: ""
|
||||||
this.id = button.id ?: ""
|
this.style = button.renderData?.style ?: 0
|
||||||
this.renderData = io.kritor.message.buttonRender {
|
}.build()
|
||||||
this.label = renderData?.label ?: ""
|
this.action = ButtonAction.newBuilder().apply {
|
||||||
this.visitedLabel = renderData?.visitedLabel ?: ""
|
this.type = button.action?.type?:0
|
||||||
this.style = renderData?.style ?: 0
|
this.permission = ButtonActionPermission.newBuilder().apply {
|
||||||
|
this.type = button.action?.permission?.type?:0
|
||||||
|
button.action?.permission?.specifyRoleIds?.let {
|
||||||
|
this.addAllRoleIds(it)
|
||||||
}
|
}
|
||||||
this.action = io.kritor.message.buttonAction {
|
button.action?.permission?.specifyUserIds?.let {
|
||||||
this.type = action?.type ?: 0
|
this.addAllUserIds(it)
|
||||||
this.permission = buttonActionPermission {
|
}
|
||||||
this.type = permission?.type ?: 0
|
}.build()
|
||||||
this.roleIds.addAll(
|
this.unsupportedTips = button.action?.unsupportTips ?: ""
|
||||||
permission?.specifyRoleIds ?: emptyList()
|
this.data = button.action?.data ?: ""
|
||||||
|
this.reply = button.action?.reply ?: false
|
||||||
|
this.enter = button.action?.enter ?: false
|
||||||
|
}.build()
|
||||||
|
}.build()
|
||||||
|
})
|
||||||
|
}.build()
|
||||||
|
})
|
||||||
|
this.applicationId = buttonExtra.field1?.appid?.toLong() ?: 0L
|
||||||
|
}.build()).build()
|
||||||
)
|
)
|
||||||
this.userIds.addAll(
|
|
||||||
permission?.specifyUserIds ?: emptyList()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
this.unsupportedTips = action?.unsupportTips ?: ""
|
|
||||||
this.data = action?.data ?: ""
|
|
||||||
this.reply = action?.reply ?: false
|
|
||||||
this.enter = action?.enter ?: false
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
package qq.service.msg
|
package qq.service.msg
|
||||||
|
|
||||||
import com.tencent.mobileqq.qroute.QRoute
|
import com.tencent.mobileqq.qroute.QRoute
|
||||||
import com.tencent.qqnt.kernel.nativeinterface.*
|
|
||||||
import com.tencent.qqnt.kernel.nativeinterface.Contact
|
import com.tencent.qqnt.kernel.nativeinterface.Contact
|
||||||
|
import com.tencent.qqnt.kernel.nativeinterface.MsgConstant
|
||||||
|
import com.tencent.qqnt.kernel.nativeinterface.MsgElement
|
||||||
import com.tencent.qqnt.msg.api.IMsgService
|
import com.tencent.qqnt.msg.api.IMsgService
|
||||||
import io.kritor.message.*
|
import io.kritor.message.*
|
||||||
import kotlinx.coroutines.suspendCancellableCoroutine
|
import kotlinx.coroutines.suspendCancellableCoroutine
|
||||||
@ -54,12 +55,12 @@ private object ReqMsgConvertor {
|
|||||||
val text = element.textElement
|
val text = element.textElement
|
||||||
val elem = Element.newBuilder()
|
val elem = Element.newBuilder()
|
||||||
if (text.atType != MsgConstant.ATTYPEUNKNOWN) {
|
if (text.atType != MsgConstant.ATTYPEUNKNOWN) {
|
||||||
elem.setAt(atElement {
|
elem.setAt(AtElement.newBuilder().apply {
|
||||||
this.uid = text.atNtUid
|
this.uid = text.atNtUid
|
||||||
this.uin = ContactHelper.getUinByUidAsync(text.atNtUid).toLong()
|
this.uin = ContactHelper.getUinByUidAsync(text.atNtUid).toLong()
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
elem.setText(textElement {
|
elem.setText(TextElement.newBuilder().apply {
|
||||||
this.text = text.content
|
this.text = text.content
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -70,28 +71,32 @@ private object ReqMsgConvertor {
|
|||||||
val face = element.faceElement
|
val face = element.faceElement
|
||||||
val elem = Element.newBuilder()
|
val elem = Element.newBuilder()
|
||||||
if (face.faceType == 5) {
|
if (face.faceType == 5) {
|
||||||
elem.setPoke(pokeElement {
|
elem.setPoke(PokeElement.newBuilder().apply {
|
||||||
this.id = face.vaspokeId
|
this.id = face.vaspokeId
|
||||||
this.type = face.pokeType
|
this.type = face.pokeType
|
||||||
this.strength = face.pokeStrength
|
this.strength = face.pokeStrength
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
when (face.faceIndex) {
|
when (face.faceIndex) {
|
||||||
114 -> elem.setBasketball(basketballElement {
|
114 -> elem.setBasketball(BasketballElement.newBuilder().apply {
|
||||||
this.id = face.resultId.ifNullOrEmpty { "0" }?.toInt() ?: 0
|
this.id = face.resultId.ifNullOrEmpty { "0" }?.toInt() ?: 0
|
||||||
})
|
})
|
||||||
358 -> elem.setDice(diceElement {
|
|
||||||
|
358 -> elem.setDice(DiceElement.newBuilder().apply {
|
||||||
this.id = face.resultId.ifNullOrEmpty { "0" }?.toInt() ?: 0
|
this.id = face.resultId.ifNullOrEmpty { "0" }?.toInt() ?: 0
|
||||||
})
|
})
|
||||||
359 -> elem.setRps(rpsElement {
|
|
||||||
|
359 -> elem.setRps(RpsElement.newBuilder().apply {
|
||||||
this.id = face.resultId.ifNullOrEmpty { "0" }?.toInt() ?: 0
|
this.id = face.resultId.ifNullOrEmpty { "0" }?.toInt() ?: 0
|
||||||
})
|
})
|
||||||
394 -> elem.setFace(faceElement {
|
|
||||||
|
394 -> elem.setFace(FaceElement.newBuilder().apply {
|
||||||
this.id = face.faceIndex
|
this.id = face.faceIndex
|
||||||
this.isBig = face.faceType == 3
|
this.isBig = face.faceType == 3
|
||||||
this.result = face.resultId.ifNullOrEmpty { "1" }?.toInt() ?: 1
|
this.result = face.resultId.ifNullOrEmpty { "1" }?.toInt() ?: 1
|
||||||
})
|
})
|
||||||
else -> elem.setFace(faceElement {
|
|
||||||
|
else -> elem.setFace(FaceElement.newBuilder().apply {
|
||||||
this.id = face.faceIndex
|
this.id = face.faceIndex
|
||||||
this.isBig = face.faceType == 3
|
this.isBig = face.faceType == 3
|
||||||
})
|
})
|
||||||
@ -129,7 +134,7 @@ private object ReqMsgConvertor {
|
|||||||
LogCenter.log({ "receive image: $image" }, Level.DEBUG)
|
LogCenter.log({ "receive image: $image" }, Level.DEBUG)
|
||||||
|
|
||||||
val elem = Element.newBuilder()
|
val elem = Element.newBuilder()
|
||||||
elem.setImage(imageElement {
|
elem.setImage(ImageElement.newBuilder().apply {
|
||||||
this.file = md5
|
this.file = md5
|
||||||
this.url = when (contact.chatType) {
|
this.url = when (contact.chatType) {
|
||||||
MsgConstant.KCHATTYPEDISC, MsgConstant.KCHATTYPEGROUP -> RichProtoSvc.getGroupPicDownUrl(
|
MsgConstant.KCHATTYPEDISC, MsgConstant.KCHATTYPEGROUP -> RichProtoSvc.getGroupPicDownUrl(
|
||||||
@ -169,7 +174,8 @@ private object ReqMsgConvertor {
|
|||||||
|
|
||||||
else -> throw UnsupportedOperationException("Not supported chat type: ${contact.chatType}")
|
else -> throw UnsupportedOperationException("Not supported chat type: ${contact.chatType}")
|
||||||
}
|
}
|
||||||
this.type = if (image.isFlashPic == true) ImageType.FLASH else if (image.original) ImageType.ORIGIN else ImageType.COMMON
|
this.type =
|
||||||
|
if (image.isFlashPic == true) ImageType.FLASH else if (image.original) ImageType.ORIGIN else ImageType.COMMON
|
||||||
this.subType = image.picSubType
|
this.subType = image.picSubType
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -184,10 +190,14 @@ private object ReqMsgConvertor {
|
|||||||
ptt.fileName.substring(5)
|
ptt.fileName.substring(5)
|
||||||
else ptt.md5HexStr
|
else ptt.md5HexStr
|
||||||
|
|
||||||
elem.setVoice(voiceElement {
|
elem.setVoice(VoiceElement.newBuilder().apply {
|
||||||
this.url = when (contact.chatType) {
|
this.url = when (contact.chatType) {
|
||||||
MsgConstant.KCHATTYPEC2C -> RichProtoSvc.getC2CPttDownUrl("0", ptt.fileUuid)
|
MsgConstant.KCHATTYPEC2C -> RichProtoSvc.getC2CPttDownUrl("0", ptt.fileUuid)
|
||||||
MsgConstant.KCHATTYPEGROUP, MsgConstant.KCHATTYPEGUILD -> RichProtoSvc.getGroupPttDownUrl("0", md5.hex2ByteArray(), ptt.fileUuid)
|
MsgConstant.KCHATTYPEGROUP, MsgConstant.KCHATTYPEGUILD -> RichProtoSvc.getGroupPttDownUrl(
|
||||||
|
"0",
|
||||||
|
md5.hex2ByteArray(),
|
||||||
|
ptt.fileUuid
|
||||||
|
)
|
||||||
|
|
||||||
else -> throw UnsupportedOperationException("Not supported chat type: ${contact.chatType}")
|
else -> throw UnsupportedOperationException("Not supported chat type: ${contact.chatType}")
|
||||||
}
|
}
|
||||||
@ -208,7 +218,7 @@ private object ReqMsgConvertor {
|
|||||||
it[it.size - 2].hex2ByteArray()
|
it[it.size - 2].hex2ByteArray()
|
||||||
}
|
}
|
||||||
} else video.fileName.split(".")[0].hex2ByteArray()
|
} else video.fileName.split(".")[0].hex2ByteArray()
|
||||||
elem.setVideo(videoElement {
|
elem.setVideo(VideoElement.newBuilder().apply {
|
||||||
this.file = md5.toHexString()
|
this.file = md5.toHexString()
|
||||||
this.url = when (contact.chatType) {
|
this.url = when (contact.chatType) {
|
||||||
MsgConstant.KCHATTYPEGROUP -> RichProtoSvc.getGroupVideoDownUrl("0", md5, video.fileUuid)
|
MsgConstant.KCHATTYPEGROUP -> RichProtoSvc.getGroupVideoDownUrl("0", md5, video.fileUuid)
|
||||||
@ -232,8 +242,8 @@ private object ReqMsgConvertor {
|
|||||||
when (data["app"].asString) {
|
when (data["app"].asString) {
|
||||||
"com.tencent.multimsg" -> {
|
"com.tencent.multimsg" -> {
|
||||||
val info = data["meta"].asJsonObject["detail"].asJsonObject
|
val info = data["meta"].asJsonObject["detail"].asJsonObject
|
||||||
elem.setForward(forwardElement {
|
elem.setForward(ForwardElement.newBuilder().apply {
|
||||||
this.id = info["resid"].asString
|
this.resId = info["resid"].asString
|
||||||
this.uniseq = info["uniseq"].asString
|
this.uniseq = info["uniseq"].asString
|
||||||
this.summary = info["summary"].asString
|
this.summary = info["summary"].asString
|
||||||
this.description = info["news"].asJsonArray.joinToString("\n") {
|
this.description = info["news"].asJsonArray.joinToString("\n") {
|
||||||
@ -244,7 +254,7 @@ private object ReqMsgConvertor {
|
|||||||
|
|
||||||
"com.tencent.troopsharecard" -> {
|
"com.tencent.troopsharecard" -> {
|
||||||
val info = data["meta"].asJsonObject["contact"].asJsonObject
|
val info = data["meta"].asJsonObject["contact"].asJsonObject
|
||||||
elem.setContact(contactElement {
|
elem.setContact(ContactElement.newBuilder().apply {
|
||||||
this.scene = Scene.GROUP
|
this.scene = Scene.GROUP
|
||||||
this.peer = info["jumpUrl"].asString.split("group_code=")[1]
|
this.peer = info["jumpUrl"].asString.split("group_code=")[1]
|
||||||
})
|
})
|
||||||
@ -252,7 +262,7 @@ private object ReqMsgConvertor {
|
|||||||
|
|
||||||
"com.tencent.contact.lua" -> {
|
"com.tencent.contact.lua" -> {
|
||||||
val info = data["meta"].asJsonObject["contact"].asJsonObject
|
val info = data["meta"].asJsonObject["contact"].asJsonObject
|
||||||
elem.setContact(contactElement {
|
elem.setContact(ContactElement.newBuilder().apply {
|
||||||
this.scene = Scene.FRIEND
|
this.scene = Scene.FRIEND
|
||||||
this.peer = info["jumpUrl"].asString.split("uin=")[1]
|
this.peer = info["jumpUrl"].asString.split("uin=")[1]
|
||||||
})
|
})
|
||||||
@ -260,7 +270,7 @@ private object ReqMsgConvertor {
|
|||||||
|
|
||||||
"com.tencent.map" -> {
|
"com.tencent.map" -> {
|
||||||
val info = data["meta"].asJsonObject["Location.Search"].asJsonObject
|
val info = data["meta"].asJsonObject["Location.Search"].asJsonObject
|
||||||
elem.setLocation(locationElement {
|
elem.setLocation(LocationElement.newBuilder().apply {
|
||||||
this.lat = info["lat"].asString.toFloat()
|
this.lat = info["lat"].asString.toFloat()
|
||||||
this.lon = info["lng"].asString.toFloat()
|
this.lon = info["lng"].asString.toFloat()
|
||||||
this.address = info["address"].asString
|
this.address = info["address"].asString
|
||||||
@ -268,7 +278,7 @@ private object ReqMsgConvertor {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
else -> elem.setJson(jsonElement {
|
else -> elem.setJson(JsonElement.newBuilder().apply {
|
||||||
this.json = data.toString()
|
this.json = data.toString()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -278,11 +288,12 @@ private object ReqMsgConvertor {
|
|||||||
suspend fun convertReply(contact: Contact, element: MsgElement): Result<Element> {
|
suspend fun convertReply(contact: Contact, element: MsgElement): Result<Element> {
|
||||||
val reply = element.replyElement
|
val reply = element.replyElement
|
||||||
val elem = Element.newBuilder()
|
val elem = Element.newBuilder()
|
||||||
elem.setReply(replyElement {
|
elem.setReply(ReplyElement.newBuilder().apply {
|
||||||
val msgSeq = reply.replayMsgSeq
|
val msgSeq = reply.replayMsgSeq
|
||||||
val sourceRecords = withTimeoutOrNull(3000) {
|
val sourceRecords = withTimeoutOrNull(3000) {
|
||||||
suspendCancellableCoroutine {
|
suspendCancellableCoroutine {
|
||||||
QRoute.api(IMsgService::class.java).getMsgsBySeqAndCount(contact, msgSeq, 1, true) { _, _, records ->
|
QRoute.api(IMsgService::class.java)
|
||||||
|
.getMsgsBySeqAndCount(contact, msgSeq, 1, true) { _, _, records ->
|
||||||
it.resume(records)
|
it.resume(records)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -307,11 +318,17 @@ private object ReqMsgConvertor {
|
|||||||
val fileSubId = fileMsg.fileSubId ?: ""
|
val fileSubId = fileMsg.fileSubId ?: ""
|
||||||
val url = when (contact.chatType) {
|
val url = when (contact.chatType) {
|
||||||
MsgConstant.KCHATTYPEC2C -> RichProtoSvc.getC2CFileDownUrl(fileId, fileSubId)
|
MsgConstant.KCHATTYPEC2C -> RichProtoSvc.getC2CFileDownUrl(fileId, fileSubId)
|
||||||
MsgConstant.KCHATTYPEGUILD -> RichProtoSvc.getGuildFileDownUrl(contact.guildId, contact.longPeer().toString(), fileId, bizId)
|
MsgConstant.KCHATTYPEGUILD -> RichProtoSvc.getGuildFileDownUrl(
|
||||||
|
contact.guildId,
|
||||||
|
contact.longPeer().toString(),
|
||||||
|
fileId,
|
||||||
|
bizId
|
||||||
|
)
|
||||||
|
|
||||||
else -> RichProtoSvc.getGroupFileDownUrl(contact.longPeer(), fileId, bizId)
|
else -> RichProtoSvc.getGroupFileDownUrl(contact.longPeer(), fileId, bizId)
|
||||||
}
|
}
|
||||||
val elem = Element.newBuilder()
|
val elem = Element.newBuilder()
|
||||||
elem.setFile(fileElement {
|
elem.setFile(FileElement.newBuilder().apply {
|
||||||
this.name = fileName
|
this.name = fileName
|
||||||
this.size = fileSize
|
this.size = fileSize
|
||||||
this.url = url
|
this.url = url
|
||||||
@ -326,7 +343,7 @@ private object ReqMsgConvertor {
|
|||||||
suspend fun convertMarkdown(contact: Contact, element: MsgElement): Result<Element> {
|
suspend fun convertMarkdown(contact: Contact, element: MsgElement): Result<Element> {
|
||||||
val markdown = element.markdownElement
|
val markdown = element.markdownElement
|
||||||
val elem = Element.newBuilder()
|
val elem = Element.newBuilder()
|
||||||
elem.setMarkdown(markdownElement {
|
elem.setMarkdown(MarkdownElement.newBuilder().apply {
|
||||||
this.markdown = markdown.content
|
this.markdown = markdown.content
|
||||||
})
|
})
|
||||||
return Result.success(elem.build())
|
return Result.success(elem.build())
|
||||||
@ -335,7 +352,7 @@ private object ReqMsgConvertor {
|
|||||||
suspend fun convertBubbleFace(contact: Contact, element: MsgElement): Result<Element> {
|
suspend fun convertBubbleFace(contact: Contact, element: MsgElement): Result<Element> {
|
||||||
val bubbleFace = element.faceBubbleElement
|
val bubbleFace = element.faceBubbleElement
|
||||||
val elem = Element.newBuilder()
|
val elem = Element.newBuilder()
|
||||||
elem.setBubbleFace(bubbleFaceElement {
|
elem.setBubbleFace(BubbleFaceElement.newBuilder().apply {
|
||||||
this.id = bubbleFace.yellowFaceInfo.index
|
this.id = bubbleFace.yellowFaceInfo.index
|
||||||
this.count = bubbleFace.faceCount ?: 1
|
this.count = bubbleFace.faceCount ?: 1
|
||||||
})
|
})
|
||||||
@ -345,38 +362,38 @@ private object ReqMsgConvertor {
|
|||||||
suspend fun convertInlineKeyboard(contact: Contact, element: MsgElement): Result<Element> {
|
suspend fun convertInlineKeyboard(contact: Contact, element: MsgElement): Result<Element> {
|
||||||
val inlineKeyboard = element.inlineKeyboardElement
|
val inlineKeyboard = element.inlineKeyboardElement
|
||||||
val elem = Element.newBuilder()
|
val elem = Element.newBuilder()
|
||||||
elem.setButton(buttonElement {
|
elem.setButton(ButtonElement.newBuilder().apply {
|
||||||
inlineKeyboard.rows.forEach { row ->
|
this.addAllRows(inlineKeyboard.rows.map { row ->
|
||||||
this.rows.add(row {
|
ButtonRow.newBuilder().apply {
|
||||||
row.buttons.forEach buttonsLoop@ { button ->
|
this.addAllButtons(row.buttons.map { button ->
|
||||||
if (button == null) return@buttonsLoop
|
Button.newBuilder().apply {
|
||||||
this.buttons.add(button {
|
|
||||||
this.id = button.id
|
this.id = button.id
|
||||||
this.action = buttonAction {
|
this.renderData = ButtonRender.newBuilder().apply {
|
||||||
|
this.label = button.label ?: ""
|
||||||
|
this.visitedLabel = button.visitedLabel ?: ""
|
||||||
|
this.style = button.style
|
||||||
|
}.build()
|
||||||
|
this.action = ButtonAction.newBuilder().apply {
|
||||||
this.type = button.type
|
this.type = button.type
|
||||||
this.permission = buttonActionPermission {
|
this.permission = ButtonActionPermission.newBuilder().apply {
|
||||||
this.type = button.permissionType
|
this.type = button.permissionType
|
||||||
button.specifyRoleIds?.let {
|
button.specifyRoleIds?.let {
|
||||||
this.roleIds.addAll(it)
|
this.addAllRoleIds(it)
|
||||||
}
|
}
|
||||||
button.specifyTinyids?.let {
|
button.specifyTinyids?.let {
|
||||||
this.userIds.addAll(it)
|
this.addAllUserIds(it)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}.build()
|
||||||
this.unsupportedTips = button.unsupportTips ?: ""
|
this.unsupportedTips = button.unsupportTips ?: ""
|
||||||
this.data = button.data ?: ""
|
this.data = button.data ?: ""
|
||||||
this.reply = button.isReply
|
this.reply = button.isReply
|
||||||
this.enter = button.enter
|
this.enter = button.enter
|
||||||
}
|
}.build()
|
||||||
this.renderData = buttonRender {
|
}.build()
|
||||||
this.label = button.label ?: ""
|
|
||||||
this.visitedLabel = button.visitedLabel ?: ""
|
|
||||||
this.style = button.style
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
}
|
}.build()
|
||||||
})
|
})
|
||||||
}
|
this.applicationId = inlineKeyboard.botAppid
|
||||||
})
|
})
|
||||||
return Result.success(elem.build())
|
return Result.success(elem.build())
|
||||||
}
|
}
|
||||||
|
@ -443,7 +443,7 @@ suspend fun List<Element>.toRichText(contact: Contact): Result<Pair<String, Rich
|
|||||||
ElementType.GIFT -> throw UnsupportedOperationException("Unsupported ElementType.GIFT")
|
ElementType.GIFT -> throw UnsupportedOperationException("Unsupported ElementType.GIFT")
|
||||||
ElementType.MARKET_FACE -> throw UnsupportedOperationException("Unsupported ElementType.MARKET_FACE")
|
ElementType.MARKET_FACE -> throw UnsupportedOperationException("Unsupported ElementType.MARKET_FACE")
|
||||||
ElementType.FORWARD -> {
|
ElementType.FORWARD -> {
|
||||||
val resId = it.forward.id
|
val resId = it.forward.resId
|
||||||
val filename = UUID.randomUUID().toString().uppercase()
|
val filename = UUID.randomUUID().toString().uppercase()
|
||||||
var content = it.forward.summary
|
var content = it.forward.summary
|
||||||
val descriptions = it.forward.description
|
val descriptions = it.forward.description
|
||||||
@ -552,7 +552,7 @@ suspend fun List<Element>.toRichText(contact: Contact): Result<Pair<String, Rich
|
|||||||
)
|
)
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
appid = 0
|
appid = it.button.applicationId.toULong()
|
||||||
)
|
)
|
||||||
).toByteArray(),
|
).toByteArray(),
|
||||||
businessType = 1
|
businessType = 1
|
||||||
|
Loading…
x
Reference in New Issue
Block a user