4 Commits

Author SHA1 Message Date
4f1d19fcbd upgrade kotlin version to 1.9.22 2024-02-24 16:25:31 +08:00
9a85e4d537 replace all group_id and user_id to Long 2024-02-24 16:25:31 +08:00
fac92d8094 Merge remote-tracking branch 'origin/master' 2024-02-24 12:32:02 +08:00
605f58da47 Shamrock: Using the NT kernel to upload resources
Signed-off-by: 白池 <whitechi73@outlook.com>
2024-02-24 12:31:51 +08:00
63 changed files with 474 additions and 391 deletions

View File

@ -17,7 +17,7 @@ android {
minSdk = 27 minSdk = 27
targetSdk = 34 targetSdk = 34
versionCode = getVersionCode() versionCode = getVersionCode()
versionName = "1.0.8" + ".r${getGitCommitCount()}." + getVersionName() versionName = "1.0.9" + ".r${getGitCommitCount()}." + getVersionName()
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables { vectorDrawables {
@ -92,7 +92,7 @@ android {
compose = true compose = true
} }
composeOptions { composeOptions {
kotlinCompilerExtensionVersion = "1.5.4" kotlinCompilerExtensionVersion = "1.5.10"
} }
packaging { packaging {
jniLibs { jniLibs {
@ -127,11 +127,6 @@ android {
} }
configureAppSigningConfigsForRelease(project) configureAppSigningConfigsForRelease(project)
packagingOptions {
jniLibs {
useLegacyPackaging = true
}
}
} }
fun configureAppSigningConfigsForRelease(project: Project) { fun configureAppSigningConfigsForRelease(project: Project) {

View File

@ -39,7 +39,6 @@ add_library(${CMAKE_PROJECT_NAME} SHARED
md5.cpp md5.cpp
cqcode.cpp cqcode.cpp
silk.cpp silk.cpp
group_honor.cpp
message.cpp message.cpp
shamrock.cpp) shamrock.cpp)

View File

@ -299,6 +299,16 @@ object ShamrockConfig {
return preferences.getBoolean("enable_self_msg", false) return preferences.getBoolean("enable_self_msg", false)
} }
fun enableOldBDH(ctx: Context): Boolean {
val preferences = ctx.getSharedPreferences("config", 0)
return preferences.getBoolean("enable_old_bdh", false)
}
fun setEnableOldBDH(ctx: Context, v: Boolean) {
val preferences = ctx.getSharedPreferences("config", 0)
preferences.edit().putBoolean("enable_old_bdh", v).apply()
}
fun enableSyncMsgAsSentMsg(ctx: Context): Boolean { fun enableSyncMsgAsSentMsg(ctx: Context): Boolean {
val preferences = ctx.getSharedPreferences("config", 0) val preferences = ctx.getSharedPreferences("config", 0)
return preferences.getBoolean("enable_sync_msg_as_sent_msg", false) return preferences.getBoolean("enable_sync_msg_as_sent_msg", false)
@ -334,7 +344,6 @@ object ShamrockConfig {
"inject_packet" to preferences.getBoolean("inject_packet", false), "inject_packet" to preferences.getBoolean("inject_packet", false),
"debug" to preferences.getBoolean("debug", false), "debug" to preferences.getBoolean("debug", false),
"anti_qq_trace" to preferences.getBoolean("anti_qq_trace", true), "anti_qq_trace" to preferences.getBoolean("anti_qq_trace", true),
//"auto_clear" to preferences.getBoolean("auto_clear", false),
"ssl_private_pwd" to preferences.getString("ssl_private_pwd", ""), "ssl_private_pwd" to preferences.getString("ssl_private_pwd", ""),
"key_store" to preferences.getString("key_store", ""), "key_store" to preferences.getString("key_store", ""),
"enable_self_msg" to preferences.getBoolean("enable_self_msg", false), "enable_self_msg" to preferences.getBoolean("enable_self_msg", false),
@ -343,7 +352,8 @@ object ShamrockConfig {
"alive_reply" to preferences.getBoolean("alive_reply", false), "alive_reply" to preferences.getBoolean("alive_reply", false),
"enable_sync_msg_as_sent_msg" to preferences.getBoolean("enable_sync_msg_as_sent_msg", false), "enable_sync_msg_as_sent_msg" to preferences.getBoolean("enable_sync_msg_as_sent_msg", false),
"disable_auto_sync_setting" to preferences.getBoolean("disable_auto_sync_setting", false), "disable_auto_sync_setting" to preferences.getBoolean("disable_auto_sync_setting", false),
"forbid_useless_process" to preferences.getBoolean("forbid_useless_process", false) "forbid_useless_process" to preferences.getBoolean("forbid_useless_process", false),
"enable_old_bdh" to preferences.getBoolean("enable_old_bdh", false),
) )
} }

View File

@ -102,7 +102,7 @@ fun LabFragment() {
Function( Function(
title = "禁止无用进程", title = "禁止无用进程",
desc = "禁止QQ生成无用进程浪费内存", desc = "禁止QQ生成无用进程浪费内存,可能造成部分功能闪退。",
descColor = color, descColor = color,
isSwitch = ShamrockConfig.isForbidUselessProcess(ctx) isSwitch = ShamrockConfig.isForbidUselessProcess(ctx)
) { ) {
@ -221,7 +221,7 @@ fun LabFragment() {
}.onSuccess { }.onSuccess {
Function( Function(
title = "反检测加强", title = "反检测加强",
desc = "可能导致某些设备频繁闪退", desc = "可能导致某些设备频繁闪退,将拦截环境包上报。",
descColor = color, descColor = color,
isSwitch = it.getBoolean("super_anti", false) isSwitch = it.getBoolean("super_anti", false)
) { v -> ) { v ->
@ -295,17 +295,16 @@ fun LabFragment() {
return@Function true return@Function true
} }
/*
Function( Function(
title = "使用纯数字ECHO", title = "启用旧版资源上传系统",
desc = "在部分强类型语言框架,需要打开开关。", desc = "如果NT内核无法上传资源打开开关。",
descColor = it, descColor = it,
isSwitch = ShamrockConfig.isEchoNumber(ctx) isSwitch = ShamrockConfig.enableOldBDH(ctx)
) { ) {
ShamrockConfig.setEchoNumber(ctx, it) ShamrockConfig.setEnableOldBDH(ctx, it)
ShamrockConfig.pushUpdate(ctx) ShamrockConfig.pushUpdate(ctx)
return@Function true return@Function true
}*/ }
} }
} }
} }

View File

@ -1,6 +1,6 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules. // Top-level build file where you can add configuration options common to all sub-projects/modules.
plugins { plugins {
id("com.android.application") version "8.2.0" apply false id("com.android.application") version "8.2.0" apply false
id("org.jetbrains.kotlin.android") version "1.9.20" apply false id("org.jetbrains.kotlin.android") version "1.9.22" apply false
id("com.android.library") version "8.2.0" apply false id("com.android.library") version "8.2.0" apply false
} }

View File

@ -26,7 +26,7 @@ buildscript {
} }
} }
dependencies { dependencies {
classpath("com.android.tools:r8:8.2.26") classpath("com.android.tools:r8:8.2.47")
} }
} }

View File

@ -88,16 +88,16 @@ internal object CardSvc: BaseSvc() {
return rsp.signed_ark_msg.get() return rsp.signed_ark_msg.get()
} }
suspend fun getProfileCard(uin: String): Result<Card> { suspend fun getProfileCard(uin: Long): Result<Card> {
return getProfileCardFromCache(uin).onFailure { return getProfileCardFromCache(uin).onFailure {
return refreshAndGetProfileCard(uin) return refreshAndGetProfileCard(uin)
} }
} }
fun getProfileCardFromCache(uin: String): Result<Card> { fun getProfileCardFromCache(uin: Long): Result<Card> {
val profileDataService = app val profileDataService = app
.getRuntimeService(IProfileDataService::class.java, "all") .getRuntimeService(IProfileDataService::class.java, "all")
val card = profileDataService.getProfileCard(uin, true) val card = profileDataService.getProfileCard(uin.toString(), true)
return if (card == null || card.strNick.isNullOrEmpty()) { return if (card == null || card.strNick.isNullOrEmpty()) {
Result.failure(Exception("unable to fetch profile card")) Result.failure(Exception("unable to fetch profile card"))
} else { } else {
@ -105,7 +105,7 @@ internal object CardSvc: BaseSvc() {
} }
} }
suspend fun refreshAndGetProfileCard(uin: String): Result<Card> { suspend fun refreshAndGetProfileCard(uin: Long): Result<Card> {
val dataService = app val dataService = app
.getRuntimeService(IProfileDataService::class.java, "all") .getRuntimeService(IProfileDataService::class.java, "all")
val card = refreshCardLock.withLock { val card = refreshCardLock.withLock {
@ -122,7 +122,7 @@ internal object CardSvc: BaseSvc() {
} }
}) })
app.getRuntimeService(IProfileProtocolService::class.java, "all") app.getRuntimeService(IProfileProtocolService::class.java, "all")
.requestProfileCard(app.currentUin, uin, 12, 0L, 0.toByte(), 0L, 0L, null, "", 0L, 10004, null, 0.toByte()) .requestProfileCard(app.currentUin, uin.toString(), 12, 0L, 0.toByte(), 0L, 0L, null, "", 0L, 10004, null, 0.toByte())
} }
} }
return if (card == null || card.strNick.isNullOrEmpty()) { return if (card == null || card.strNick.isNullOrEmpty()) {

View File

@ -23,7 +23,7 @@ import protobuf.group_file_common.FolderInfo as GroupFileCommonFolderInfo
import protobuf.auto.toByteArray import protobuf.auto.toByteArray
internal object FileSvc: BaseSvc() { internal object FileSvc: BaseSvc() {
suspend fun createFileFolder(groupId: String, folderName: String, parentFolderId: String = "/"): Result<GroupFileCommonFolderInfo> { suspend fun createFileFolder(groupId: Long, folderName: String, parentFolderId: String = "/"): Result<GroupFileCommonFolderInfo> {
val data = Oidb0x6d7ReqBody( val data = Oidb0x6d7ReqBody(
createFolder = CreateFolderReq( createFolder = CreateFolderReq(
groupCode = groupId.toULong(), groupCode = groupId.toULong(),
@ -45,7 +45,7 @@ internal object FileSvc: BaseSvc() {
return Result.success(rsp.createFolder!!.folderInfo!!) return Result.success(rsp.createFolder!!.folderInfo!!)
} }
suspend fun deleteGroupFolder(groupId: String, folderUid: String): Boolean { suspend fun deleteGroupFolder(groupId: Long, folderUid: String): Boolean {
val buffer = sendOidbAW("OidbSvc.0x6d7_1", 1751, 1, Oidb0x6d7ReqBody( val buffer = sendOidbAW("OidbSvc.0x6d7_1", 1751, 1, Oidb0x6d7ReqBody(
deleteFolder = DeleteFolderReq( deleteFolder = DeleteFolderReq(
groupCode = groupId.toULong(), groupCode = groupId.toULong(),
@ -59,7 +59,7 @@ internal object FileSvc: BaseSvc() {
return rsp.deleteFolder?.retCode == 0 return rsp.deleteFolder?.retCode == 0
} }
suspend fun moveGroupFolder(groupId: String, folderUid: String, newParentFolderUid: String): Boolean { suspend fun moveGroupFolder(groupId: Long, folderUid: String, newParentFolderUid: String): Boolean {
val buffer = sendOidbAW("OidbSvc.0x6d7_2", 1751, 2, Oidb0x6d7ReqBody( val buffer = sendOidbAW("OidbSvc.0x6d7_2", 1751, 2, Oidb0x6d7ReqBody(
moveFolder = MoveFolderReq( moveFolder = MoveFolderReq(
groupCode = groupId.toULong(), groupCode = groupId.toULong(),
@ -74,7 +74,7 @@ internal object FileSvc: BaseSvc() {
return rsp.moveFolder?.retCode == 0 return rsp.moveFolder?.retCode == 0
} }
suspend fun renameFolder(groupId: String, folderUid: String, name: String): Boolean { suspend fun renameFolder(groupId: Long, folderUid: String, name: String): Boolean {
val buffer = sendOidbAW("OidbSvc.0x6d7_3", 1751, 3, Oidb0x6d7ReqBody( val buffer = sendOidbAW("OidbSvc.0x6d7_3", 1751, 3, Oidb0x6d7ReqBody(
renameFolder = RenameFolderReq( renameFolder = RenameFolderReq(
groupCode = groupId.toULong(), groupCode = groupId.toULong(),
@ -89,10 +89,10 @@ internal object FileSvc: BaseSvc() {
return rsp.renameFolder?.retCode == 0 return rsp.renameFolder?.retCode == 0
} }
suspend fun deleteGroupFile(groupId: String, bizId: Int, fileUid: String): Boolean { suspend fun deleteGroupFile(groupId: Long, bizId: Int, fileUid: String): Boolean {
val oidb0x6d6ReqBody = oidb_0x6d6.ReqBody().apply { val oidb0x6d6ReqBody = oidb_0x6d6.ReqBody().apply {
delete_file_req.set(oidb_0x6d6.DeleteFileReqBody().apply { delete_file_req.set(oidb_0x6d6.DeleteFileReqBody().apply {
uint64_group_code.set(groupId.toLong()) uint64_group_code.set(groupId)
uint32_app_id.set(3) uint32_app_id.set(3)
uint32_bus_id.set(bizId) uint32_bus_id.set(bizId)
str_parent_folder_id.set("/") str_parent_folder_id.set("/")

View File

@ -156,18 +156,18 @@ internal object GroupSvc: BaseSvc() {
}) })
} }
fun poke(groupId: String, userId: String) { fun poke(groupId: Long, userId: Long) {
val req = oidb_cmd0xed3.ReqBody().apply { val req = oidb_cmd0xed3.ReqBody().apply {
uint64_group_code.set(groupId.toLong()) uint64_group_code.set(groupId)
uint64_to_uin.set(userId.toLong()) uint64_to_uin.set(userId)
uint32_msg_seq.set(0) uint32_msg_seq.set(0)
} }
sendOidb("OidbSvc.0xed3", 3795, 1, req.toByteArray()) sendOidb("OidbSvc.0xed3", 3795, 1, req.toByteArray())
} }
suspend fun getGroupMemberList(groupId: String, refresh: Boolean): Result<List<TroopMemberInfo>> { suspend fun getGroupMemberList(groupId: Long, refresh: Boolean): Result<List<TroopMemberInfo>> {
val service = app.getRuntimeService(ITroopMemberInfoService::class.java, "all") val service = app.getRuntimeService(ITroopMemberInfoService::class.java, "all")
var memberList = service.getAllTroopMembers(groupId) var memberList = service.getAllTroopMembers(groupId.toString())
if (refresh || memberList == null) { if (refresh || memberList == null) {
memberList = requestTroopMemberInfo(service, groupId).onFailure { memberList = requestTroopMemberInfo(service, groupId).onFailure {
return Result.failure(Exception("获取群成员列表失败")) return Result.failure(Exception("获取群成员列表失败"))
@ -227,26 +227,26 @@ internal object GroupSvc: BaseSvc() {
} ?: Result.failure(Exception("获取群信息超时")) } ?: Result.failure(Exception("获取群信息超时"))
} }
suspend fun getGroupInfo(groupId: String, refresh: Boolean): Result<TroopInfo> { suspend fun getGroupInfo(groupId: Long, refresh: Boolean): Result<TroopInfo> {
val service = app val service = app
.getRuntimeService(ITroopInfoService::class.java, "all") .getRuntimeService(ITroopInfoService::class.java, "all")
val groupInfo = getGroupInfo(groupId) val groupInfo = getGroupInfo(groupId)
return if(refresh || !service.isTroopCacheInited || groupInfo.troopuin.isNullOrBlank()) { return if(refresh || !service.isTroopCacheInited || groupInfo.troopuin.isNullOrBlank()) {
requestGroupInfo(service, groupId.toLong()) requestGroupInfo(service, groupId)
} else { } else {
Result.success(groupInfo) Result.success(groupInfo)
} }
} }
suspend fun setGroupUniqueTitle(groupId: String, userId: String, title: String) { suspend fun setGroupUniqueTitle(groupId: Long, userId: Long, title: String) {
val localMemberInfo = getTroopMemberInfoByUin(groupId, userId, true).getOrThrow() val localMemberInfo = getTroopMemberInfoByUin(groupId, userId, true).getOrThrow()
val req = Oidb_0x8fc.ReqBody() val req = Oidb_0x8fc.ReqBody()
req.uint64_group_code.set(groupId.toLong()) req.uint64_group_code.set(groupId)
val memberInfo = Oidb_0x8fc.MemberInfo() val memberInfo = Oidb_0x8fc.MemberInfo()
memberInfo.uint64_uin.set(userId.toLong()) memberInfo.uint64_uin.set(userId)
memberInfo.bytes_uin_name.set(ByteStringMicro.copyFromUtf8(localMemberInfo.troopnick.ifEmpty { memberInfo.bytes_uin_name.set(ByteStringMicro.copyFromUtf8(localMemberInfo.troopnick.ifEmpty {
localMemberInfo.troopremark.ifNullOrEmpty("") localMemberInfo.troopremark.ifNullOrEmpty("")
})) }))
@ -371,17 +371,17 @@ internal object GroupSvc: BaseSvc() {
sendOidb("OidbSvc.0x8a0_0", 2208, 0, reqBody.toByteArray()) sendOidb("OidbSvc.0x8a0_0", 2208, 0, reqBody.toByteArray())
} }
fun getGroupInfo(groupId: String): TroopInfo { fun getGroupInfo(groupId: Long): TroopInfo {
val runtime = AppRuntimeFetcher.appRuntime as QQAppInterface val runtime = AppRuntimeFetcher.appRuntime as QQAppInterface
val service = runtime val service = runtime
.getRuntimeService(ITroopInfoService::class.java, "all") .getRuntimeService(ITroopInfoService::class.java, "all")
return service.getTroopInfo(groupId) return service.getTroopInfo(groupId.toString())
} }
fun getAdminList( fun getAdminList(
groupId: String, groupId: Long,
withOwner: Boolean = false withOwner: Boolean = false
): List<Long> { ): List<Long> {
val groupInfo = getGroupInfo(groupId) val groupInfo = getGroupInfo(groupId)
@ -399,39 +399,39 @@ internal object GroupSvc: BaseSvc() {
suspend fun getMemberRole(groupId: Long, memberUin: Long): MemberRole { suspend fun getMemberRole(groupId: Long, memberUin: Long): MemberRole {
if (!GET_MEMBER_ROLE_BY_NT) { if (!GET_MEMBER_ROLE_BY_NT) {
return when (memberUin) { return when (memberUin) {
getOwner(groupId.toString()) -> MemberRole.Owner getOwner(groupId) -> MemberRole.Owner
in getAdminList(groupId.toString()) -> MemberRole.Admin in getAdminList(groupId) -> MemberRole.Admin
else -> MemberRole.Member else -> MemberRole.Member
} }
} }
return when(getTroopMemberInfoByUinViaNt(groupId.toString(), memberUin, 3000).getOrNull()?.role) { return when(getTroopMemberInfoByUinViaNt(groupId, memberUin, 3000).getOrNull()?.role) {
com.tencent.qqnt.kernel.nativeinterface.MemberRole.STRANGER -> MemberRole.Stranger com.tencent.qqnt.kernel.nativeinterface.MemberRole.STRANGER -> MemberRole.Stranger
com.tencent.qqnt.kernel.nativeinterface.MemberRole.MEMBER -> MemberRole.Member com.tencent.qqnt.kernel.nativeinterface.MemberRole.MEMBER -> MemberRole.Member
com.tencent.qqnt.kernel.nativeinterface.MemberRole.ADMIN -> MemberRole.Admin com.tencent.qqnt.kernel.nativeinterface.MemberRole.ADMIN -> MemberRole.Admin
com.tencent.qqnt.kernel.nativeinterface.MemberRole.OWNER -> MemberRole.Owner com.tencent.qqnt.kernel.nativeinterface.MemberRole.OWNER -> MemberRole.Owner
com.tencent.qqnt.kernel.nativeinterface.MemberRole.UNSPECIFIED, null -> when (memberUin) { com.tencent.qqnt.kernel.nativeinterface.MemberRole.UNSPECIFIED, null -> when (memberUin) {
getOwner(groupId.toString()) -> MemberRole.Owner getOwner(groupId) -> MemberRole.Owner
in getAdminList(groupId.toString()) -> MemberRole.Admin in getAdminList(groupId) -> MemberRole.Admin
else -> MemberRole.Member else -> MemberRole.Member
} }
} }
} }
fun getOwner(groupId: String): Long { fun getOwner(groupId: Long): Long {
val groupInfo = getGroupInfo(groupId) val groupInfo = getGroupInfo(groupId)
return groupInfo.troopowneruin?.toLong() ?: 0 return groupInfo.troopowneruin?.toLong() ?: 0
} }
fun isOwner(groupId: String): Boolean { fun isOwner(groupId: Long): Boolean {
val groupInfo = getGroupInfo(groupId) val groupInfo = getGroupInfo(groupId)
return groupInfo.troopowneruin == app.account return groupInfo.troopowneruin == app.account
} }
fun isAdmin(groupId: String): Boolean { fun isAdmin(groupId: Long): Boolean {
val service = app val service = app
.getRuntimeService(ITroopInfoService::class.java, "all") .getRuntimeService(ITroopInfoService::class.java, "all")
val groupInfo = service.getTroopInfo(groupId) val groupInfo = service.getTroopInfo(groupId.toString())
return groupInfo.isAdmin || groupInfo.troopowneruin == app.account return groupInfo.isAdmin || groupInfo.troopowneruin == app.account
} }
@ -444,7 +444,7 @@ internal object GroupSvc: BaseSvc() {
} }
} }
fun modifyTroopName(groupId: String, name: String) { fun modifyTroopName(groupId: Long, name: String) {
val businessHandler = app.getBusinessHandler(BusinessHandlerFactory.TROOP_MODIFY_HANDLER) val businessHandler = app.getBusinessHandler(BusinessHandlerFactory.TROOP_MODIFY_HANDLER)
if (!GroupSvc::METHOD_REQ_MODIFY_GROUP_NAME.isInitialized) { if (!GroupSvc::METHOD_REQ_MODIFY_GROUP_NAME.isInitialized) {
@ -535,17 +535,17 @@ internal object GroupSvc: BaseSvc() {
} }
suspend fun getTroopMemberInfoByUin( suspend fun getTroopMemberInfoByUin(
groupId: String, groupId: Long,
uin: String, uin: Long,
refresh: Boolean = false refresh: Boolean = false
): Result<TroopMemberInfo> { ): Result<TroopMemberInfo> {
val service = app.getRuntimeService(ITroopMemberInfoService::class.java, "all") val service = app.getRuntimeService(ITroopMemberInfoService::class.java, "all")
var info = service.getTroopMember(groupId, uin) var info = service.getTroopMember(groupId.toString(), uin.toString())
if (refresh || !service.isMemberInCache(groupId, uin) || info == null || info.troopnick == null) { if (refresh || !service.isMemberInCache(groupId.toString(), uin.toString()) || info == null || info.troopnick == null) {
info = requestTroopMemberInfo(service, groupId.toLong(), uin.toLong()).getOrNull() info = requestTroopMemberInfo(service, groupId, uin).getOrNull()
} }
if (info == null) { if (info == null) {
info = getTroopMemberInfoByUinViaNt(groupId, uin.toLong()).getOrNull()?.let { info = getTroopMemberInfoByUinViaNt(groupId, uin).getOrNull()?.let {
TroopMemberInfo().apply { TroopMemberInfo().apply {
troopnick = it.cardName troopnick = it.cardName
friendnick = it.nick friendnick = it.nick
@ -555,7 +555,7 @@ internal object GroupSvc: BaseSvc() {
try { try {
if (info != null && (info.alias == null || info.alias.isBlank())) { if (info != null && (info.alias == null || info.alias.isBlank())) {
val req = group_member_info.ReqBody() val req = group_member_info.ReqBody()
req.uint64_group_code.set(groupId.toLong()) req.uint64_group_code.set(groupId)
req.uint64_uin.set(uin.toLong()) req.uint64_uin.set(uin.toLong())
req.bool_new_client.set(true) req.bool_new_client.set(true)
req.uint32_client_type.set(1) req.uint32_client_type.set(1)
@ -590,17 +590,17 @@ internal object GroupSvc: BaseSvc() {
} }
suspend fun getTroopMemberInfoByUinV2( suspend fun getTroopMemberInfoByUinV2(
groupId: String, groupId: Long,
uin: String, uin: Long,
refresh: Boolean = false refresh: Boolean = false
): Result<TroopMemberInfo> { ): Result<TroopMemberInfo> {
val service = app.getRuntimeService(ITroopMemberInfoService::class.java, "all") val service = app.getRuntimeService(ITroopMemberInfoService::class.java, "all")
var info = service.getTroopMember(groupId, uin) var info = service.getTroopMember(groupId.toString(), uin.toString())
if (refresh || !service.isMemberInCache(groupId, uin) || info == null || info.troopnick == null) { if (refresh || !service.isMemberInCache(groupId.toString(), uin.toString()) || info == null || info.troopnick == null) {
info = requestTroopMemberInfo(service, groupId.toLong(), uin.toLong(), timeout = 2000).getOrNull() info = requestTroopMemberInfo(service, groupId, uin, timeout = 2000).getOrNull()
} }
if (info == null) { if (info == null) {
info = getTroopMemberInfoByUinViaNt(groupId, uin.toLong(), timeout = 2000L).getOrNull()?.let { info = getTroopMemberInfoByUinViaNt(groupId, uin, timeout = 2000L).getOrNull()?.let {
TroopMemberInfo().apply { TroopMemberInfo().apply {
troopnick = it.cardName troopnick = it.cardName
friendnick = it.nick friendnick = it.nick
@ -610,8 +610,8 @@ internal object GroupSvc: BaseSvc() {
try { try {
if (info != null && (info.alias == null || info.alias.isBlank())) { if (info != null && (info.alias == null || info.alias.isBlank())) {
val req = group_member_info.ReqBody() val req = group_member_info.ReqBody()
req.uint64_group_code.set(groupId.toLong()) req.uint64_group_code.set(groupId)
req.uint64_uin.set(uin.toLong()) req.uint64_uin.set(uin)
req.bool_new_client.set(true) req.bool_new_client.set(true)
req.uint32_client_type.set(1) req.uint32_client_type.set(1)
req.uint32_rich_card_name_ver.set(1) req.uint32_rich_card_name_ver.set(1)
@ -645,7 +645,7 @@ internal object GroupSvc: BaseSvc() {
} }
suspend fun getTroopMemberInfoByUinViaNt( suspend fun getTroopMemberInfoByUinViaNt(
groupId: String, groupId: Long,
qq: Long, qq: Long,
timeout: Long = 5000L timeout: Long = 5000L
): Result<MemberInfo> { ): Result<MemberInfo> {
@ -655,7 +655,7 @@ internal object GroupSvc: BaseSvc() {
val groupService = sessionService.groupService val groupService = sessionService.groupService
val info = withTimeoutOrNull(timeout) { val info = withTimeoutOrNull(timeout) {
suspendCancellableCoroutine { suspendCancellableCoroutine {
groupService.getTransferableMemberInfo(groupId.toLong()) { code, _, data -> groupService.getTransferableMemberInfo(groupId) { code, _, data ->
if (code != 0) { if (code != 0) {
it.resume(null) it.resume(null)
return@getTransferableMemberInfo return@getTransferableMemberInfo
@ -703,16 +703,16 @@ internal object GroupSvc: BaseSvc() {
} }
} }
private suspend fun requestTroopMemberInfo(service: ITroopMemberInfoService, groupId: String): Result<List<TroopMemberInfo>> { private suspend fun requestTroopMemberInfo(service: ITroopMemberInfoService, groupId: Long): Result<List<TroopMemberInfo>> {
val info = RefreshTroopMemberListLock.withLock { val info = RefreshTroopMemberListLock.withLock {
service.deleteTroopMembers(groupId) service.deleteTroopMembers(groupId.toString())
refreshTroopMemberList(groupId) refreshTroopMemberList(groupId)
withTimeoutOrNull(10000) { withTimeoutOrNull(10000) {
var memberList: List<TroopMemberInfo>? var memberList: List<TroopMemberInfo>?
do { do {
delay(100) delay(100)
memberList = service.getAllTroopMembers(groupId) memberList = service.getAllTroopMembers(groupId.toString())
} while (memberList.isNullOrEmpty()) } while (memberList.isNullOrEmpty())
return@withTimeoutOrNull memberList return@withTimeoutOrNull memberList
} }
@ -745,7 +745,7 @@ internal object GroupSvc: BaseSvc() {
} }
} }
private fun refreshTroopMemberList(groupId: String) { private fun refreshTroopMemberList(groupId: Long) {
val app = AppRuntimeFetcher.appRuntime val app = AppRuntimeFetcher.appRuntime
if (app !is AppInterface) if (app !is AppInterface)
throw RuntimeException("AppRuntime cannot cast to AppInterface") throw RuntimeException("AppRuntime cannot cast to AppInterface")
@ -763,7 +763,7 @@ internal object GroupSvc: BaseSvc() {
} }
} }
METHOD_REQ_TROOP_MEM_LIST.invoke(businessHandler, true, groupId, groupUin2GroupCode(groupId.toLong()).toString(), 5) METHOD_REQ_TROOP_MEM_LIST.invoke(businessHandler, true, groupId, groupUin2GroupCode(groupId).toString(), 5)
} }
private fun refreshTroopList() { private fun refreshTroopList() {

View File

@ -31,7 +31,7 @@ import kotlin.coroutines.resume
import kotlin.coroutines.suspendCoroutine import kotlin.coroutines.suspendCoroutine
internal object MsgSvc : BaseSvc() { internal object MsgSvc : BaseSvc() {
suspend fun prepareTempChatFromGroup( private suspend fun prepareTempChatFromGroup(
groupId: String, groupId: String,
peerId: String peerId: String
): Result<Unit> { ): Result<Unit> {

View File

@ -78,7 +78,7 @@ internal object VisitorSvc: BaseSvc() {
if(count !in 1 .. 20) { if(count !in 1 .. 20) {
return Result.failure(IllegalArgumentException("vote count must be in 1 .. 20")) return Result.failure(IllegalArgumentException("vote count must be in 1 .. 20"))
} }
val card = CardSvc.getProfileCard(target.toString()).onFailure { val card = CardSvc.getProfileCard(target).onFailure {
return Result.failure(RuntimeException("unable to fetch contact info")) return Result.failure(RuntimeException("unable to fetch contact info"))
}.getOrThrow() }.getOrThrow()
sendExtra("VisitorSvc.ReqFavorite") { sendExtra("VisitorSvc.ReqFavorite") {

View File

@ -111,7 +111,7 @@ internal object MessageElementMaker {
else -> { else -> {
qq = qqStr.toLong() qq = qqStr.toLong()
type = 0 type = 0
"@" + (data["name"].asStringOrNull ?: GroupSvc.getTroopMemberInfoByUinV2(peerId, qqStr, true) "@" + (data["name"].asStringOrNull ?: GroupSvc.getTroopMemberInfoByUinV2(peerId.toLong(), qq, true)
.let { .let {
val info = it.getOrNull() val info = it.getOrNull()
if (info == null) if (info == null)
@ -138,11 +138,11 @@ internal object MessageElementMaker {
MsgConstant.KCHATTYPEC2C -> { MsgConstant.KCHATTYPEC2C -> {
data.checkAndThrow("qq") data.checkAndThrow("qq")
val qq = data["qq"].asString val qq = data["qq"].asLong
val display = val display =
"@" + (data["name"].asStringOrNull ?: CardSvc.getProfileCard(qq) "@" + (data["name"].asStringOrNull ?: CardSvc.getProfileCard(qq)
.onSuccess { .onSuccess {
it.strNick.ifNullOrEmpty(qq) it.strNick.ifNullOrEmpty(qq.toString())
}.onFailure { }.onFailure {
LogCenter.log("无法获取QQ信息: $qq", Level.WARN) LogCenter.log("无法获取QQ信息: $qq", Level.WARN)
}) })

View File

@ -37,6 +37,7 @@ import moe.fuqiuluo.shamrock.helper.LogicException
import moe.fuqiuluo.shamrock.helper.MessageHelper import moe.fuqiuluo.shamrock.helper.MessageHelper
import moe.fuqiuluo.shamrock.helper.MusicHelper import moe.fuqiuluo.shamrock.helper.MusicHelper
import moe.fuqiuluo.shamrock.helper.ParamsException import moe.fuqiuluo.shamrock.helper.ParamsException
import moe.fuqiuluo.shamrock.remote.service.config.ShamrockConfig
import moe.fuqiuluo.shamrock.tools.* import moe.fuqiuluo.shamrock.tools.*
import moe.fuqiuluo.shamrock.utils.AudioUtils import moe.fuqiuluo.shamrock.utils.AudioUtils
import moe.fuqiuluo.shamrock.utils.FileUtils import moe.fuqiuluo.shamrock.utils.FileUtils
@ -91,7 +92,12 @@ internal object MsgElementMaker {
operator fun get(type: String): IMsgElementMaker? = makerMap[type] operator fun get(type: String): IMsgElementMaker? = makerMap[type]
private suspend fun createInlineKeywordElem(chatType: Int, msgId: Long, peerId: String, data: JsonObject): Result<MsgElement> { private suspend fun createInlineKeywordElem(
chatType: Int,
msgId: Long,
peerId: String,
data: JsonObject
): Result<MsgElement> {
fun tryNewKeyboardButton(btn: JsonObject): InlineKeyboardButton { fun tryNewKeyboardButton(btn: JsonObject): InlineKeyboardButton {
return runCatching { return runCatching {
InlineKeyboardButton( InlineKeyboardButton(
@ -126,6 +132,7 @@ internal object MsgElementMaker {
) )
} }
} }
val elem = MsgElement() val elem = MsgElement()
elem.elementType = MsgConstant.KELEMTYPEINLINEKEYBOARD elem.elementType = MsgConstant.KELEMTYPEINLINEKEYBOARD
val rows = arrayListOf<InlineKeyboardRow>() val rows = arrayListOf<InlineKeyboardRow>()
@ -289,7 +296,7 @@ internal object MsgElementMaker {
data: JsonObject data: JsonObject
): Result<MsgElement> { ): Result<MsgElement> {
data.checkAndThrow("id") data.checkAndThrow("id")
GroupSvc.poke(peerId, data["id"].asString) GroupSvc.poke(peerId.toLong(), data["id"].asLong)
return Result.failure(ActionMsgException) return Result.failure(ActionMsgException)
} }
@ -715,11 +722,13 @@ internal object MsgElementMaker {
AudioUtils.obtainVideoCover(file.absolutePath, thumbPath!!) AudioUtils.obtainVideoCover(file.absolutePath, thumbPath!!)
} }
Transfer with when (chatType) { if (ShamrockConfig.enableOldBDH()) {
MsgConstant.KCHATTYPEGROUP -> Troop(peerId) Transfer with when (chatType) {
MsgConstant.KCHATTYPEC2C -> Private(peerId) MsgConstant.KCHATTYPEGROUP -> Troop(peerId)
else -> error("Not supported chatType($chatType) for VideoMsg") MsgConstant.KCHATTYPEC2C -> Private(peerId)
} trans VideoResource(file, File(thumbPath.toString())) else -> error("Not supported chatType($chatType) for VideoMsg")
} trans VideoResource(file, File(thumbPath.toString()))
}
video.fileTime = AudioUtils.getVideoTime(file) video.fileTime = AudioUtils.getVideoTime(file)
video.fileSize = file.length() video.fileSize = file.length()
@ -746,10 +755,10 @@ internal object MsgElementMaker {
data.checkAndThrow("qq") data.checkAndThrow("qq")
val elem = MsgElement() val elem = MsgElement()
val qq = data["qq"].asString val qqStr = data["qq"].asString
val at = TextElement() val at = TextElement()
when (qq) { when (qqStr) {
"0", "all" -> { "0", "all" -> {
at.content = "@全体成员" at.content = "@全体成员"
at.atType = MsgConstant.ATTYPEALL at.atType = MsgConstant.ATTYPEALL
@ -770,25 +779,26 @@ internal object MsgElementMaker {
} }
else -> { else -> {
val qq = qqStr.toLong()
val name = data["name"].asStringOrNull val name = data["name"].asStringOrNull
if (name == null) { if (name == null) {
val info = GroupSvc.getTroopMemberInfoByUinV2(peerId, qq, true).onFailure { val info = GroupSvc.getTroopMemberInfoByUinV2(peerId.toLong(), qq, true).onFailure {
LogCenter.log("无法获取群成员信息: $qq", Level.ERROR) LogCenter.log("无法获取群成员信息: $qqStr", Level.ERROR)
}.getOrNull() }.getOrNull()
if (info != null) { if (info != null) {
at.content = "@${ at.content = "@${
info.troopnick info.troopnick
.ifNullOrEmpty(info.friendnick) .ifNullOrEmpty(info.friendnick)
.ifNullOrEmpty(qq) .ifNullOrEmpty(qqStr)
}" }"
} else { } else {
at.content = "@$qq" at.content = "@$qqStr"
} }
} else { } else {
at.content = "@$name" at.content = "@$name"
} }
at.atType = MsgConstant.ATTYPEONE at.atType = MsgConstant.ATTYPEONE
at.atNtUid = ContactHelper.getUidByUinAsync(qq.toLong()) at.atNtUid = ContactHelper.getUidByUinAsync(qq)
} }
} }
@ -849,36 +859,55 @@ internal object MsgElementMaker {
else -> { else -> {
LogCenter.log({ "Audio To SILK: $file" }, Level.DEBUG) LogCenter.log({ "Audio To SILK: $file" }, Level.DEBUG)
val result = AudioUtils.audioToSilk(file) val result = AudioUtils.audioToSilk(file)
ptt.duration = result.first ptt.duration = runCatching {
QRoute.api(IAIOPttApi::class.java)
.getPttFileDuration(result.second.absolutePath)
}.getOrElse {
result.first
}
file = result.second file = result.second
ptt.formatType = MsgConstant.KPTTFORMATTYPESILK ptt.formatType = MsgConstant.KPTTFORMATTYPESILK
} }
} }
//val msgService = NTServiceFetcher.kernelService.msgService!!
//val originalPath = msgService.getRichMediaFilePathForMobileQQSend(RichMediaFilePathInfo(
// MsgConstant.KELEMTYPEPTT, 0, ptt.md5HexStr, file.name, 1, 0, null, "", true
//))!!
//if (!QQNTWrapperUtil.CppProxy.fileIsExist(originalPath) || QQNTWrapperUtil.CppProxy.getFileSize(originalPath) != file.length()) {
// QQNTWrapperUtil.CppProxy.copyFile(file.absolutePath, originalPath)
//}
if (!(Transfer with when (chatType) {
MsgConstant.KCHATTYPEGROUP -> Troop(peerId)
MsgConstant.KCHATTYPEC2C -> Private(peerId)
MsgConstant.KCHATTYPETEMPC2CFROMGROUP -> Private(peerId)
else -> error("Not supported chatType($chatType) for RecordMsg")
} trans VoiceResource(file))
) {
return Result.failure(RuntimeException("上传语音失败: $file"))
}
val elem = MsgElement() val elem = MsgElement()
elem.elementType = MsgConstant.KELEMTYPEPTT elem.elementType = MsgConstant.KELEMTYPEPTT
ptt.md5HexStr = QQNTWrapperUtil.CppProxy.genFileMd5Hex(file.absolutePath) ptt.md5HexStr = QQNTWrapperUtil.CppProxy.genFileMd5Hex(file.absolutePath)
ptt.fileName = file.name if (ShamrockConfig.enableOldBDH()) {
ptt.filePath = file.absolutePath if (!(Transfer with when (chatType) {
ptt.fileSize = file.length() MsgConstant.KCHATTYPEGROUP -> Troop(peerId)
MsgConstant.KCHATTYPEC2C -> Private(peerId)
MsgConstant.KCHATTYPETEMPC2CFROMGROUP -> Private(peerId)
else -> error("Not supported chatType($chatType) for RecordMsg")
} trans VoiceResource(file))
) {
return Result.failure(RuntimeException("上传语音失败: $file"))
}
ptt.filePath = file.absolutePath
} else {
val msgService = NTServiceFetcher.kernelService.msgService!!
val originalPath = msgService.getRichMediaFilePathForMobileQQSend(
RichMediaFilePathInfo(
MsgConstant.KELEMTYPEPTT, 0, ptt.md5HexStr, file.name, 1, 0, null, "", true
)
)
if (!QQNTWrapperUtil.CppProxy.fileIsExist(originalPath) || QQNTWrapperUtil.CppProxy.getFileSize(originalPath) != file.length()) {
QQNTWrapperUtil.CppProxy.copyFile(file.absolutePath, originalPath)
}
if (originalPath != null) {
ptt.filePath = originalPath
} else {
ptt.filePath = file.absolutePath
}
}
ptt.canConvert2Text = true
ptt.fileId = 0
ptt.fileUuid = ""
ptt.text = ""
if (!isMagic) { if (!isMagic) {
ptt.voiceType = MsgConstant.KPTTVOICETYPESOUNDRECORD ptt.voiceType = MsgConstant.KPTTVOICETYPESOUNDRECORD
@ -888,11 +917,6 @@ internal object MsgElementMaker {
ptt.voiceChangeType = MsgConstant.KPTTVOICECHANGETYPEECHO ptt.voiceChangeType = MsgConstant.KPTTVOICECHANGETYPEECHO
} }
ptt.canConvert2Text = false
ptt.fileId = 0
ptt.fileUuid = ""
ptt.text = ""
elem.pttElement = ptt elem.pttElement = ptt
return Result.success(elem) return Result.success(elem)
@ -927,11 +951,13 @@ internal object MsgElementMaker {
} }
requireNotNull(file) requireNotNull(file)
Transfer with when (chatType) { if (ShamrockConfig.enableOldBDH()) {
MsgConstant.KCHATTYPEGROUP -> Troop(peerId) Transfer with when (chatType) {
MsgConstant.KCHATTYPEC2C -> Private(peerId) MsgConstant.KCHATTYPEGROUP -> Troop(peerId)
else -> error("Not supported chatType($chatType) for PictureMsg") MsgConstant.KCHATTYPEC2C -> Private(peerId)
} trans PictureResource(file) else -> error("Not supported chatType($chatType) for PictureMsg")
} trans PictureResource(file)
}
val elem = MsgElement() val elem = MsgElement()
elem.elementType = MsgConstant.KELEMTYPEPIC elem.elementType = MsgConstant.KELEMTYPEPIC

View File

@ -0,0 +1,63 @@
package moe.fuqiuluo.shamrock.helper
import moe.fuqiuluo.shamrock.remote.service.data.GroupMemberHonor
object TroopHonorHelper {
data class Honor(
val id: Int,
val name: String,
val iconUrl: String,
val priority: Int
)
private val honorList = listOf(
Honor(1, "龙王", "https://qzonestyle.gtimg.cn/aoi/sola/20200213150116_n4PxCiurbm.png", 1),
Honor(2, "群聊之火", "https://qzonestyle.gtimg.cn/aoi/sola/20200217190136_92JEGFKC5k.png", 3),
Honor(3, "群聊炽焰", "https://qzonestyle.gtimg.cn/aoi/sola/20200217190204_zgCTeSrMq1.png", 4),
Honor(5, "冒尖小春笋", "https://qzonestyle.gtimg.cn/aoi/sola/20200213150335_tUJCAtoKVP.png", 5),
Honor(6, "快乐源泉", "https://qzonestyle.gtimg.cn/aoi/sola/20200213150434_3tDmsJExCP.png", 7),
Honor(7, "学术新星", "https://sola.gtimg.cn/aoi/sola/20200515140645_j0X6gbuHNP.png", 8),
Honor(8, "顶尖学霸", "https://sola.gtimg.cn/aoi/sola/20200515140639_0CtWOpfVzK.png", 9),
Honor(9, "至尊学神", "https://sola.gtimg.cn/aoi/sola/20200515140628_P8UEYBjMBT.png", 10),
Honor(10, "一笔当先", "https://sola.gtimg.cn/aoi/sola/20200515140654_4r94tSCdaB.png", 11),
Honor(11, "奋进小翠竹", "https://sola.gtimg.cn/aoi/sola/20200812151819_wbj6z2NGoB.png", 6),
Honor(12, "氛围魔杖", "https://sola.gtimg.cn/aoi/sola/20200812151831_4ZJgQCaD1H.png", 2),
Honor(13, "壕礼皇冠", "https://sola.gtimg.cn/aoi/sola/20200930154050_juZOAMg7pt.png", 12)
)
fun decodeHonor(userId: Long, honorId: Int, honorFlag: Byte): GroupMemberHonor? {
val flag = calcHonorFlag(honorId, honorFlag)
val honor = if ((honorId != 1 && honorId != 2 && honorId != 3) || flag != 1) {
honorList.find { it.id == honorId }
} else {
val honor = honorList.find { it.id == honorId }
honor?.let {
val url = "https://static-res.qq.com/static-res/groupInteract/vas/a/${honorId}_1.png"
it.copy(iconUrl = url)
}
}
return honor?.let {
GroupMemberHonor(
userId,
"",
it.iconUrl,
0,
it.id,
it.name
)
}
}
private fun calcHonorFlag(honorId: Int, honorFlag: Byte): Int {
val flag = honorFlag.toInt()
if (flag == 0) {
return 0
}
return when {
honorId == 1 -> flag
honorId == 2 || honorId == 3 -> flag shr 2
honorId != 4 -> 0
else -> flag shr 4
} and 3
}
}

View File

@ -23,7 +23,7 @@ internal object BanTroopMember: IActionHandler() {
duration: Int = 30 * 60, duration: Int = 30 * 60,
echo: JsonElement = EmptyJsonString echo: JsonElement = EmptyJsonString
): String { ): String {
if (!GroupSvc.isAdmin(groupId.toString())) { if (!GroupSvc.isAdmin(groupId)) {
return logic("You are not the administrator of the group.", echo) return logic("You are not the administrator of the group.", echo)
} }
GroupSvc.banMember(groupId, userId, duration) GroupSvc.banMember(groupId, userId, duration)

View File

@ -10,13 +10,13 @@ import moe.fuqiuluo.symbols.OneBotHandler
@OneBotHandler("create_group_file_folder") @OneBotHandler("create_group_file_folder")
internal object CreateGroupFileFolder: IActionHandler() { internal object CreateGroupFileFolder: IActionHandler() {
override suspend fun internalHandle(session: ActionSession): String { override suspend fun internalHandle(session: ActionSession): String {
val groupId = session.getString("group_id") val groupId = session.getLong("group_id")
val folderName = session.getString("name") val folderName = session.getString("name")
val echo = session.echo val echo = session.echo
return invoke(groupId, folderName, echo) return invoke(groupId, folderName, echo)
} }
suspend operator fun invoke(groupId: String, folderName: String, echo: JsonElement = EmptyJsonString): String { suspend operator fun invoke(groupId: Long, folderName: String, echo: JsonElement = EmptyJsonString): String {
val result = FileSvc.createFileFolder(groupId, folderName) val result = FileSvc.createFileFolder(groupId, folderName)
if (result.isFailure) { if (result.isFailure) {
return ok(msg = result.exceptionOrNull()?.message ?: "无法创建群文件夹", echo = echo) return ok(msg = result.exceptionOrNull()?.message ?: "无法创建群文件夹", echo = echo)

View File

@ -10,13 +10,13 @@ import moe.fuqiuluo.symbols.OneBotHandler
@OneBotHandler("delete_group_file") @OneBotHandler("delete_group_file")
internal object DeleteGroupFile: IActionHandler() { internal object DeleteGroupFile: IActionHandler() {
override suspend fun internalHandle(session: ActionSession): String { override suspend fun internalHandle(session: ActionSession): String {
val groupId = session.getString("group_id") val groupId = session.getLong("group_id")
val fileId = session.getString("file_id") val fileId = session.getString("file_id")
val busid = session.getInt("busid") val busid = session.getInt("busid")
return invoke(groupId, fileId, busid, session.echo) return invoke(groupId, fileId, busid, session.echo)
} }
suspend operator fun invoke(groupId: String, fileId: String, bizId: Int, echo: JsonElement = EmptyJsonString): String { suspend operator fun invoke(groupId: Long, fileId: String, bizId: Int, echo: JsonElement = EmptyJsonString): String {
if(!FileSvc.deleteGroupFile(groupId, bizId, fileId)) { if(!FileSvc.deleteGroupFile(groupId, bizId, fileId)) {
return error("删除失败", echo = echo) return error("删除失败", echo = echo)
} }

View File

@ -10,12 +10,12 @@ import moe.fuqiuluo.symbols.OneBotHandler
@OneBotHandler("delete_group_folder") @OneBotHandler("delete_group_folder")
internal object DeleteGroupFolder: IActionHandler() { internal object DeleteGroupFolder: IActionHandler() {
override suspend fun internalHandle(session: ActionSession): String { override suspend fun internalHandle(session: ActionSession): String {
val groupId = session.getString("group_id") val groupId = session.getLong("group_id")
val folderId = session.getString("folder_id") val folderId = session.getString("folder_id")
return invoke(groupId, folderId, session.echo) return invoke(groupId, folderId, session.echo)
} }
suspend operator fun invoke(groupId: String, folderId: String, echo: JsonElement = EmptyJsonString): String { suspend operator fun invoke(groupId: Long, folderId: String, echo: JsonElement = EmptyJsonString): String {
if(!FileSvc.deleteGroupFolder(groupId, folderId)) { if(!FileSvc.deleteGroupFolder(groupId, folderId)) {
return error(why = "删除群文件夹失败", echo = echo) return error(why = "删除群文件夹失败", echo = echo)
} }

View File

@ -10,12 +10,12 @@ import moe.fuqiuluo.symbols.OneBotHandler
@OneBotHandler("get_group_file_system_info") @OneBotHandler("get_group_file_system_info")
internal object GetGroupFileSystemInfo: IActionHandler() { internal object GetGroupFileSystemInfo: IActionHandler() {
override suspend fun internalHandle(session: ActionSession): String { override suspend fun internalHandle(session: ActionSession): String {
val groupId = session.getString("group_id") val groupId = session.getLong("group_id")
return invoke(groupId, session.echo) return invoke(groupId, session.echo)
} }
suspend operator fun invoke(groupId: String, echo: JsonElement = EmptyJsonString): String { suspend operator fun invoke(groupId: Long, echo: JsonElement = EmptyJsonString): String {
return ok(data = FileSvc.getGroupFileSystemInfo(groupId.toLong()), echo) return ok(data = FileSvc.getGroupFileSystemInfo(groupId), echo)
} }
override val requiredParams: Array<String> = arrayOf("group_id") override val requiredParams: Array<String> = arrayOf("group_id")

View File

@ -10,14 +10,14 @@ import moe.fuqiuluo.symbols.OneBotHandler
@OneBotHandler("get_group_file_url") @OneBotHandler("get_group_file_url")
internal object GetGroupFileUrl: IActionHandler() { internal object GetGroupFileUrl: IActionHandler() {
override suspend fun internalHandle(session: ActionSession): String { override suspend fun internalHandle(session: ActionSession): String {
val groupId = session.getString("group_id") val groupId = session.getLong("group_id")
val fileId = session.getString("file_id") val fileId = session.getString("file_id")
val busid = session.getInt("busid") val busid = session.getInt("busid")
return invoke(groupId, fileId, busid, session.echo) return invoke(groupId, fileId, busid, session.echo)
} }
suspend operator fun invoke(groupId: String, fileId: String, busid: Int, echo: JsonElement = EmptyJsonString): String { suspend operator fun invoke(groupId: Long, fileId: String, busid: Int, echo: JsonElement = EmptyJsonString): String {
return ok(data = FileSvc.getGroupFileInfo(groupId.toLong(), fileId, busid), echo = echo) return ok(data = FileSvc.getGroupFileInfo(groupId, fileId, busid), echo = echo)
} }
override val requiredParams: Array<String> = arrayOf("group_id", "file_id", "busid") override val requiredParams: Array<String> = arrayOf("group_id", "file_id", "busid")

View File

@ -8,7 +8,7 @@ import moe.fuqiuluo.symbols.OneBotHandler
@OneBotHandler("get_group_msg_history") @OneBotHandler("get_group_msg_history")
internal object GetGroupMsgHistory: IActionHandler() { internal object GetGroupMsgHistory: IActionHandler() {
override suspend fun internalHandle(session: ActionSession): String { override suspend fun internalHandle(session: ActionSession): String {
val groupId = session.getString("group_id") val groupId = session.getLong("group_id")
val cnt = session.getIntOrNull("count") ?: 20 val cnt = session.getIntOrNull("count") ?: 20
val startId = session.getIntOrNull("message_seq")?.let { val startId = session.getIntOrNull("message_seq")?.let {
if (it == 0) return@let 0L if (it == 0) return@let 0L
@ -16,7 +16,7 @@ internal object GetGroupMsgHistory: IActionHandler() {
.messageMappingDao() .messageMappingDao()
.queryByMsgHashId(it)?.qqMsgId .queryByMsgHashId(it)?.qqMsgId
} ?: 0L } ?: 0L
return GetHistoryMsg("group", groupId, cnt, startId, session.echo) return GetHistoryMsg("group", groupId.toString(), cnt, startId, session.echo)
} }
override val requiredParams: Array<String> = arrayOf("group_id") override val requiredParams: Array<String> = arrayOf("group_id")

View File

@ -10,12 +10,12 @@ import moe.fuqiuluo.symbols.OneBotHandler
@OneBotHandler("get_group_root_files") @OneBotHandler("get_group_root_files")
internal object GetGroupRootFiles: IActionHandler() { internal object GetGroupRootFiles: IActionHandler() {
override suspend fun internalHandle(session: ActionSession): String { override suspend fun internalHandle(session: ActionSession): String {
val groupId = session.getString("group_id") val groupId = session.getLong("group_id")
return invoke(groupId, session.echo) return invoke(groupId, session.echo)
} }
suspend operator fun invoke(groupId: String, echo: JsonElement = EmptyJsonString): String { suspend operator fun invoke(groupId: Long, echo: JsonElement = EmptyJsonString): String {
FileSvc.getGroupRootFiles(groupId.toLong()).onSuccess { FileSvc.getGroupRootFiles(groupId).onSuccess {
return ok(it, echo = echo) return ok(it, echo = echo)
}.getOrNull() }.getOrNull()
return error(why = "获取失败", echo = echo) return error(why = "获取失败", echo = echo)

View File

@ -10,13 +10,13 @@ import moe.fuqiuluo.symbols.OneBotHandler
@OneBotHandler("get_group_files_by_folder") @OneBotHandler("get_group_files_by_folder")
internal object GetGroupSubFiles: IActionHandler() { internal object GetGroupSubFiles: IActionHandler() {
override suspend fun internalHandle(session: ActionSession): String { override suspend fun internalHandle(session: ActionSession): String {
val groupId = session.getString("group_id") val groupId = session.getLong("group_id")
val folderId = session.getString("folder_id") val folderId = session.getString("folder_id")
return invoke(groupId, folderId, session.echo) return invoke(groupId, folderId, session.echo)
} }
suspend operator fun invoke(groupId: String, folderId: String, echo: JsonElement = EmptyJsonString): String { suspend operator fun invoke(groupId: Long, folderId: String, echo: JsonElement = EmptyJsonString): String {
FileSvc.getGroupFiles(groupId.toLong(), folderId).onSuccess { FileSvc.getGroupFiles(groupId, folderId).onSuccess {
return ok(it, echo = echo) return ok(it, echo = echo)
}.getOrNull() }.getOrNull()
return error(why = "获取失败", echo = echo) return error(why = "获取失败", echo = echo)

View File

@ -14,7 +14,7 @@ import moe.fuqiuluo.symbols.OneBotHandler
internal object GetGuildMemberProfile: IActionHandler() { internal object GetGuildMemberProfile: IActionHandler() {
override suspend fun internalHandle(session: ActionSession): String { override suspend fun internalHandle(session: ActionSession): String {
val guildId = session.getString("guild_id").toULong() val guildId = session.getString("guild_id").toULong()
val userId = session.getString("user_id").toULong() val userId = session.getLong("user_id").toULong()
return invoke(guildId, userId, session.echo) return invoke(guildId, userId, session.echo)
} }

View File

@ -25,7 +25,7 @@ import kotlin.coroutines.suspendCoroutine
internal object GetHistoryMsg : IActionHandler() { internal object GetHistoryMsg : IActionHandler() {
override suspend fun internalHandle(session: ActionSession): String { override suspend fun internalHandle(session: ActionSession): String {
val msgType = session.getString("message_type") val msgType = session.getString("message_type")
val peerId = session.getString(if (msgType == "group") "group_id" else "user_id") val peerId = session.getLong(if (msgType == "group") "group_id" else "user_id").toString()
val cnt = session.getIntOrNull("count") ?: 20 val cnt = session.getIntOrNull("count") ?: 20
val startId = session.getIntOrNull("message_seq")?.let { val startId = session.getIntOrNull("message_seq")?.let {

View File

@ -10,12 +10,12 @@ import moe.fuqiuluo.symbols.OneBotHandler
@OneBotHandler("get_not_joined_group_info") @OneBotHandler("get_not_joined_group_info")
internal object GetNotJoinedGroupInfo: IActionHandler() { internal object GetNotJoinedGroupInfo: IActionHandler() {
override suspend fun internalHandle(session: ActionSession): String { override suspend fun internalHandle(session: ActionSession): String {
val groupId = session.getString("group_id") val groupId = session.getLong("group_id")
return invoke(groupId, session.echo) return invoke(groupId, session.echo)
} }
suspend operator fun invoke(groupId: String, echo: JsonElement = EmptyJsonString): String { suspend operator fun invoke(groupId: Long, echo: JsonElement = EmptyJsonString): String {
GroupSvc.getNotJoinedGroupInfo(groupId = groupId.toLong()).onSuccess { GroupSvc.getNotJoinedGroupInfo(groupId = groupId).onSuccess {
return ok(it, echo = echo) return ok(it, echo = echo)
}.exceptionOrNull()?.let { }.exceptionOrNull()?.let {
return error(it.message ?: "无法获取群信息", echo = echo) return error(it.message ?: "无法获取群信息", echo = echo)

View File

@ -15,7 +15,7 @@ import moe.fuqiuluo.symbols.OneBotHandler
@OneBotHandler("get_user_info", ["get_profile_card"]) @OneBotHandler("get_user_info", ["get_profile_card"])
internal object GetProfileCard: IActionHandler() { internal object GetProfileCard: IActionHandler() {
override suspend fun internalHandle(session: ActionSession): String { override suspend fun internalHandle(session: ActionSession): String {
val uin = session.getString("user_id") val uin = session.getLong("user_id")
val refresh = session.getBooleanOrDefault("refresh", session.getBooleanOrDefault("no_cache", false)) val refresh = session.getBooleanOrDefault("refresh", session.getBooleanOrDefault("no_cache", false))
var card: Card? = CardSvc.getProfileCard(uin).getOrNull() var card: Card? = CardSvc.getProfileCard(uin).getOrNull()

View File

@ -14,11 +14,11 @@ import moe.fuqiuluo.symbols.OneBotHandler
@OneBotHandler("get_stranger_info", ["_get_stranger_info"]) @OneBotHandler("get_stranger_info", ["_get_stranger_info"])
internal object GetStrangerInfo: IActionHandler() { internal object GetStrangerInfo: IActionHandler() {
override suspend fun internalHandle(session: ActionSession): String { override suspend fun internalHandle(session: ActionSession): String {
val uid = session.getString("user_id") val userId = session.getLong("user_id")
return invoke(uid, session.echo) return invoke(userId, session.echo)
} }
suspend operator fun invoke(userId: String, echo: JsonElement = EmptyJsonString): String { suspend operator fun invoke(userId: Long, echo: JsonElement = EmptyJsonString): String {
val info = CardSvc.refreshAndGetProfileCard(userId).onFailure { val info = CardSvc.refreshAndGetProfileCard(userId).onFailure {
return logic("unable to fetch stranger info", echo) return logic("unable to fetch stranger info", echo)
}.getOrThrow() }.getOrThrow()
@ -71,7 +71,7 @@ internal object GetStrangerInfo: IActionHandler() {
@Serializable @Serializable
data class StrangerInfo( data class StrangerInfo(
@SerialName("user_id") val uid: String, @SerialName("user_id") val uid: Long,
@SerialName("nickname") val nickname: String, @SerialName("nickname") val nickname: String,
@SerialName("age") val age: Byte, @SerialName("age") val age: Byte,
@SerialName("sex") val sex: String, @SerialName("sex") val sex: String,

View File

@ -2,6 +2,7 @@ package moe.fuqiuluo.shamrock.remote.action.handlers
import kotlinx.serialization.json.JsonElement import kotlinx.serialization.json.JsonElement
import moe.fuqiuluo.qqinterface.servlet.GroupSvc import moe.fuqiuluo.qqinterface.servlet.GroupSvc
import moe.fuqiuluo.shamrock.helper.TroopHonorHelper.decodeHonor
import moe.fuqiuluo.shamrock.remote.action.ActionSession import moe.fuqiuluo.shamrock.remote.action.ActionSession
import moe.fuqiuluo.shamrock.remote.action.IActionHandler import moe.fuqiuluo.shamrock.remote.action.IActionHandler
import moe.fuqiuluo.shamrock.remote.service.data.GroupAllHonor import moe.fuqiuluo.shamrock.remote.service.data.GroupAllHonor
@ -17,12 +18,12 @@ import moe.fuqiuluo.symbols.OneBotHandler
@OneBotHandler("get_group_honor_info", ["get_troop_honor_info"]) @OneBotHandler("get_group_honor_info", ["get_troop_honor_info"])
internal object GetTroopHonor: IActionHandler() { internal object GetTroopHonor: IActionHandler() {
override suspend fun internalHandle(session: ActionSession): String { override suspend fun internalHandle(session: ActionSession): String {
val groupId = session.getString("group_id") val groupId = session.getLong("group_id")
val refresh = session.getBooleanOrDefault("refresh", session.getBooleanOrDefault("no_cache", false)) val refresh = session.getBooleanOrDefault("refresh", session.getBooleanOrDefault("no_cache", false))
return invoke(groupId, refresh, session.echo) return invoke(groupId, refresh, session.echo)
} }
suspend operator fun invoke(groupId: String, refresh: Boolean, echo: JsonElement = EmptyJsonString): String { suspend operator fun invoke(groupId: Long, refresh: Boolean, echo: JsonElement = EmptyJsonString): String {
val honorInfo = ArrayList<GroupMemberHonor>() val honorInfo = ArrayList<GroupMemberHonor>()
GroupSvc.getGroupMemberList(groupId, refresh).onFailure { GroupSvc.getGroupMemberList(groupId, refresh).onFailure {
@ -30,7 +31,7 @@ internal object GetTroopHonor: IActionHandler() {
}.onSuccess { memberList -> }.onSuccess { memberList ->
memberList.forEach { member -> memberList.forEach { member ->
GroupSvc.parseHonor(member.honorList).forEach { GroupSvc.parseHonor(member.honorList).forEach {
val honor = nativeDecodeHonor(member.memberuin, it, member.mHonorRichFlag) val honor = decodeHonor(member.memberuin.toLong(), it, member.mHonorRichFlag)
if (honor != null) { if (honor != null) {
honor.nick = member.troopnick.ifEmpty { member.friendnick } honor.nick = member.troopnick.ifEmpty { member.friendnick }
honorInfo.add(honor) honorInfo.add(honor)
@ -40,7 +41,7 @@ internal object GetTroopHonor: IActionHandler() {
} }
return ok(GroupAllHonor( return ok(GroupAllHonor(
groupId = groupId.toLong(), groupId = groupId,
currentTalkActive = honorInfo.firstOrNull { currentTalkActive = honorInfo.firstOrNull {
it.id == HONOR_TALKATIVE it.id == HONOR_TALKATIVE
}, },
@ -54,6 +55,4 @@ internal object GetTroopHonor: IActionHandler() {
} }
override val requiredParams: Array<String> = arrayOf("group_id") override val requiredParams: Array<String> = arrayOf("group_id")
private external fun nativeDecodeHonor(userId: String, honorId: Int, honorFlag: Byte): GroupMemberHonor?
} }

View File

@ -11,12 +11,12 @@ import moe.fuqiuluo.symbols.OneBotHandler
@OneBotHandler("get_group_info") @OneBotHandler("get_group_info")
internal object GetTroopInfo: IActionHandler() { internal object GetTroopInfo: IActionHandler() {
override suspend fun internalHandle(session: ActionSession): String { override suspend fun internalHandle(session: ActionSession): String {
val groupId = session.getString("group_id") val groupId = session.getLong("group_id")
val refresh = session.getBooleanOrDefault("refresh", session.getBooleanOrDefault("no_cache", false)) val refresh = session.getBooleanOrDefault("refresh", session.getBooleanOrDefault("no_cache", false))
return invoke(groupId, refresh, session.echo) return invoke(groupId, refresh, session.echo)
} }
suspend operator fun invoke(groupId: String, refresh: Boolean, echo: JsonElement = EmptyJsonString): String { suspend operator fun invoke(groupId: Long, refresh: Boolean, echo: JsonElement = EmptyJsonString): String {
val groupInfo = GroupSvc.getGroupInfo(groupId, refresh).getOrNull() val groupInfo = GroupSvc.getGroupInfo(groupId, refresh).getOrNull()
return if ( groupInfo == null || groupInfo.troopuin.isNullOrBlank()) { return if ( groupInfo == null || groupInfo.troopuin.isNullOrBlank()) {
logic("Unable to obtain group information", echo) logic("Unable to obtain group information", echo)

View File

@ -30,7 +30,7 @@ internal object GetTroopList : IActionHandler() {
groupName = groupInfo.troopname ?: groupInfo.newTroopName groupName = groupInfo.troopname ?: groupInfo.newTroopName
?: groupInfo.oldTroopName, ?: groupInfo.oldTroopName,
groupRemark = groupInfo.troopRemark, groupRemark = groupInfo.troopRemark,
adminList = GroupSvc.getAdminList(groupInfo.troopuin, true), adminList = GroupSvc.getAdminList(groupInfo.troopuin.toLong(), true),
classText = groupInfo.mGroupClassExtText, classText = groupInfo.mGroupClassExtText,
isFrozen = groupInfo.mIsFreezed != 0, isFrozen = groupInfo.mIsFreezed != 0,
maxMember = groupInfo.wMemberMax, maxMember = groupInfo.wMemberMax,

View File

@ -6,7 +6,6 @@ import moe.fuqiuluo.qqinterface.servlet.GroupSvc
import moe.fuqiuluo.shamrock.remote.action.ActionSession import moe.fuqiuluo.shamrock.remote.action.ActionSession
import moe.fuqiuluo.shamrock.remote.action.IActionHandler import moe.fuqiuluo.shamrock.remote.action.IActionHandler
import moe.fuqiuluo.shamrock.remote.service.data.SimpleTroopMemberInfo import moe.fuqiuluo.shamrock.remote.service.data.SimpleTroopMemberInfo
import moe.fuqiuluo.shamrock.remote.service.data.push.MemberRole
import moe.fuqiuluo.shamrock.tools.EmptyJsonString import moe.fuqiuluo.shamrock.tools.EmptyJsonString
import moe.fuqiuluo.shamrock.tools.ifNullOrEmpty import moe.fuqiuluo.shamrock.tools.ifNullOrEmpty
import moe.fuqiuluo.symbols.OneBotHandler import moe.fuqiuluo.symbols.OneBotHandler
@ -14,20 +13,20 @@ import moe.fuqiuluo.symbols.OneBotHandler
@OneBotHandler("get_group_member_info") @OneBotHandler("get_group_member_info")
internal object GetTroopMemberInfo : IActionHandler() { internal object GetTroopMemberInfo : IActionHandler() {
override suspend fun internalHandle(session: ActionSession): String { override suspend fun internalHandle(session: ActionSession): String {
val uin = session.getString("user_id") val userId = session.getLong("user_id")
val groupId = session.getString("group_id") val groupId = session.getLong("group_id")
val refresh = session.getBooleanOrDefault("refresh", session.getBooleanOrDefault("no_cache", false)) val refresh = session.getBooleanOrDefault("refresh", session.getBooleanOrDefault("no_cache", false))
return invoke(groupId, uin, refresh, session.echo) return invoke(groupId, userId, refresh, session.echo)
} }
suspend operator fun invoke( suspend operator fun invoke(
groupId: String, groupId: Long,
uin: String, userId: Long,
refresh: Boolean, refresh: Boolean,
echo: JsonElement = EmptyJsonString echo: JsonElement = EmptyJsonString
): String { ): String {
val info = GroupSvc.getTroopMemberInfoByUin(groupId, uin, refresh).onFailure { val info = GroupSvc.getTroopMemberInfoByUin(groupId, userId, refresh).onFailure {
return error(it.message ?: "unknown error", echo) return error(it.message ?: "unknown error", echo)
}.getOrThrow() }.getOrThrow()
@ -42,7 +41,7 @@ internal object GetTroopMemberInfo : IActionHandler() {
joinTime = info.join_time, joinTime = info.join_time,
lastActiveTime = info.last_active_time, lastActiveTime = info.last_active_time,
uniqueName = info.mUniqueTitle, uniqueName = info.mUniqueTitle,
groupId = groupId.toLong(), groupId = groupId,
nick = info.friendnick.ifNullOrEmpty(info.autoremark) ?: "", nick = info.friendnick.ifNullOrEmpty(info.autoremark) ?: "",
sex = when (info.sex.toShort()) { sex = when (info.sex.toShort()) {
Card.FEMALE -> "female" Card.FEMALE -> "female"
@ -52,7 +51,7 @@ internal object GetTroopMemberInfo : IActionHandler() {
area = info.alias ?: "", area = info.alias ?: "",
lastSentTime = info.last_active_time, lastSentTime = info.last_active_time,
level = info.level, level = info.level,
role = GroupSvc.getMemberRole(groupId.toLong(), uin.toLong()), role = GroupSvc.getMemberRole(groupId, userId),
unfriendly = false, unfriendly = false,
title = info.mUniqueTitle ?: "", title = info.mUniqueTitle ?: "",
titleExpireTime = info.mUniqueTitleExpire, titleExpireTime = info.mUniqueTitleExpire,

View File

@ -14,20 +14,20 @@ import moe.fuqiuluo.symbols.OneBotHandler
@OneBotHandler("get_group_member_list") @OneBotHandler("get_group_member_list")
internal object GetTroopMemberList : IActionHandler() { internal object GetTroopMemberList : IActionHandler() {
override suspend fun internalHandle(session: ActionSession): String { override suspend fun internalHandle(session: ActionSession): String {
val groupId = session.getString("group_id") val groupId = session.getLong("group_id")
val refresh = session.getBooleanOrDefault("refresh", session.getBooleanOrDefault("no_cache", false)) val refresh = session.getBooleanOrDefault("refresh", session.getBooleanOrDefault("no_cache", false))
return invoke(groupId, refresh, session.echo) return invoke(groupId, refresh, session.echo)
} }
suspend operator fun invoke( suspend operator fun invoke(
groupId: String, groupId: Long,
refresh: Boolean, refresh: Boolean,
echo: JsonElement = EmptyJsonString echo: JsonElement = EmptyJsonString
): String { ): String {
val memberList = GroupSvc.getGroupMemberList(groupId, refresh).onFailure { val memberList = GroupSvc.getGroupMemberList(groupId, refresh).onFailure {
return error(it.message ?: "unknown error", echo, arrayResult = true) return error(it.message ?: "unknown error", echo, arrayResult = true)
}.getOrThrow() }.getOrThrow()
val prohibitedMemberList = GroupSvc.getProhibitedMemberList(groupId.toLong()) val prohibitedMemberList = GroupSvc.getProhibitedMemberList(groupId)
.getOrDefault(arrayListOf()) .getOrDefault(arrayListOf())
.associate { it.memberUin to it.shutuptimestap.toLong() } .associate { it.memberUin to it.shutuptimestap.toLong() }
return ok(arrayListOf<SimpleTroopMemberInfo>().apply { return ok(arrayListOf<SimpleTroopMemberInfo>().apply {
@ -44,7 +44,7 @@ internal object GetTroopMemberList : IActionHandler() {
joinTime = info.join_time, joinTime = info.join_time,
lastActiveTime = info.last_active_time, lastActiveTime = info.last_active_time,
uniqueName = info.mUniqueTitle, uniqueName = info.mUniqueTitle,
groupId = groupId.toLong(), groupId = groupId,
nick = info.friendnick.ifNullOrEmpty(info.autoremark) ?: "", nick = info.friendnick.ifNullOrEmpty(info.autoremark) ?: "",
sex = when (info.sex.toShort()) { sex = when (info.sex.toShort()) {
Card.FEMALE -> "female" Card.FEMALE -> "female"
@ -54,7 +54,7 @@ internal object GetTroopMemberList : IActionHandler() {
area = info.alias ?: "", area = info.alias ?: "",
lastSentTime = info.last_active_time, lastSentTime = info.last_active_time,
level = info.level, level = info.level,
role = GroupSvc.getMemberRole(groupId.toLong(), info.memberuin.toLong()) role = GroupSvc.getMemberRole(groupId, info.memberuin.toLong())
/*when { /*when {
GroupSvc.getOwner(groupId) GroupSvc.getOwner(groupId)
.toString() == info.memberuin -> MemberRole.Owner .toString() == info.memberuin -> MemberRole.Owner

View File

@ -10,12 +10,12 @@ import moe.fuqiuluo.symbols.OneBotHandler
@OneBotHandler("poke") @OneBotHandler("poke")
internal object GroupPoke: IActionHandler() { internal object GroupPoke: IActionHandler() {
override suspend fun internalHandle(session: ActionSession): String { override suspend fun internalHandle(session: ActionSession): String {
val groupId = session.getString("group_id") val groupId = session.getLong("group_id")
val userId = session.getString("user_id") val userId = session.getLong("user_id")
return invoke(groupId, userId, session.echo) return invoke(groupId, userId, session.echo)
} }
operator fun invoke(groupId: String, userId: String, echo: JsonElement = EmptyJsonString): String { operator fun invoke(groupId: Long, userId: Long, echo: JsonElement = EmptyJsonString): String {
GroupSvc.poke(groupId, userId) GroupSvc.poke(groupId, userId)
return ok("成功", echo) return ok("成功", echo)
} }

View File

@ -16,15 +16,15 @@ import kotlin.coroutines.suspendCoroutine
@OneBotHandler("is_blacklist_uin") @OneBotHandler("is_blacklist_uin")
internal object IsBlackListUin: IActionHandler() { internal object IsBlackListUin: IActionHandler() {
override suspend fun internalHandle(session: ActionSession): String { override suspend fun internalHandle(session: ActionSession): String {
val userId = session.getString("user_id") val userId = session.getLong("user_id")
return invoke(userId, session.echo) return invoke(userId, session.echo)
} }
suspend operator fun invoke(uin: String, echo: JsonElement = EmptyJsonString): String { suspend operator fun invoke(uin: Long, echo: JsonElement = EmptyJsonString): String {
val blacklistApi = QRoute.api(IProfileCardBlacklistApi::class.java) val blacklistApi = QRoute.api(IProfileCardBlacklistApi::class.java)
val isBlack = withTimeoutOrNull(5000) { val isBlack = withTimeoutOrNull(5000) {
suspendCoroutine { continuation -> suspendCoroutine { continuation ->
blacklistApi.isBlackOrBlackedUin(uin) { blacklistApi.isBlackOrBlackedUin(uin.toString()) {
continuation.resume(it) continuation.resume(it)
} }
} }

View File

@ -10,15 +10,15 @@ import moe.fuqiuluo.symbols.OneBotHandler
@OneBotHandler("leave_group", ["set_group_leave"]) @OneBotHandler("leave_group", ["set_group_leave"])
internal object LeaveTroop: IActionHandler() { internal object LeaveTroop: IActionHandler() {
override suspend fun internalHandle(session: ActionSession): String { override suspend fun internalHandle(session: ActionSession): String {
val groupId = session.getString("group_id") val groupId = session.getLong("group_id")
return invoke(groupId, session.echo) return invoke(groupId, session.echo)
} }
operator fun invoke(groupId: String, echo: JsonElement = EmptyJsonString): String { operator fun invoke(groupId: Long, echo: JsonElement = EmptyJsonString): String {
if (GroupSvc.isOwner(groupId)) { if (GroupSvc.isOwner(groupId)) {
return error("you are the owner of this group", echo) return error("you are the owner of this group", echo)
} }
GroupSvc.resignTroop(groupId.toLong()) GroupSvc.resignTroop(groupId)
return ok("成功", echo) return ok("成功", echo)
} }

View File

@ -11,17 +11,17 @@ import moe.fuqiuluo.symbols.OneBotHandler
@OneBotHandler("set_group_card") @OneBotHandler("set_group_card")
internal object ModifyTroopMemberName: IActionHandler() { internal object ModifyTroopMemberName: IActionHandler() {
override suspend fun internalHandle(session: ActionSession): String { override suspend fun internalHandle(session: ActionSession): String {
val groupId = session.getString("group_id") val groupId = session.getLong("group_id")
val userId = session.getString("user_id") val userId = session.getLong("user_id")
val name = session.getStringOrNull("card") ?: "" val name = session.getStringOrNull("card") ?: ""
return invoke(groupId, userId, name, session.echo) return invoke(groupId, userId, name, session.echo)
} }
operator fun invoke(groupId: String, userId: String, card: String, echo: JsonElement = EmptyJsonString): String { operator fun invoke(groupId: Long, userId: Long, card: String, echo: JsonElement = EmptyJsonString): String {
if (!GroupSvc.isAdmin(groupId) && userId != TicketSvc.getUin()) { if (!GroupSvc.isAdmin(groupId) && userId != TicketSvc.getUin().toLong()) {
return logic("you are not admin", echo) return logic("you are not admin", echo)
} }
return if(GroupSvc.modifyGroupMemberCard(groupId.toLong(), userId.toLong(), card)) return if(GroupSvc.modifyGroupMemberCard(groupId, userId, card))
ok("成功", echo) ok("成功", echo)
else error("check if member or group exist", echo) else error("check if member or group exist", echo)
} }

View File

@ -10,13 +10,13 @@ import moe.fuqiuluo.symbols.OneBotHandler
@OneBotHandler("set_group_name") @OneBotHandler("set_group_name")
internal object ModifyTroopName: IActionHandler() { internal object ModifyTroopName: IActionHandler() {
override suspend fun internalHandle(session: ActionSession): String { override suspend fun internalHandle(session: ActionSession): String {
val groupId = session.getString("group_id") val groupId = session.getLong("group_id")
val groupName = session.getString("group_name") val groupName = session.getString("group_name")
return invoke(groupId, groupName, session.echo) return invoke(groupId, groupName, session.echo)
} }
operator fun invoke(groupId: String, name: String, echo: JsonElement = EmptyJsonString): String { operator fun invoke(groupId: Long, name: String, echo: JsonElement = EmptyJsonString): String {
return if (GroupSvc.isAdmin(groupId)) { return if (GroupSvc.isAdmin(groupId)) {
GroupSvc.modifyTroopName(groupId, name) GroupSvc.modifyTroopName(groupId, name)
ok("成功", echo) ok("成功", echo)

View File

@ -10,13 +10,13 @@ import moe.fuqiuluo.symbols.OneBotHandler
@OneBotHandler("set_group_remark", ["modify_group_remark"]) @OneBotHandler("set_group_remark", ["modify_group_remark"])
internal object ModifyTroopRemark: IActionHandler() { internal object ModifyTroopRemark: IActionHandler() {
override suspend fun internalHandle(session: ActionSession): String { override suspend fun internalHandle(session: ActionSession): String {
val groupId = session.getString("group_id") val groupId = session.getLong("group_id")
val remark = session.getStringOrNull("remark") ?: "" val remark = session.getStringOrNull("remark") ?: ""
return invoke(groupId, remark, session.echo) return invoke(groupId, remark, session.echo)
} }
operator fun invoke(groupId: String, remark: String, echo: JsonElement = EmptyJsonString): String { operator fun invoke(groupId: Long, remark: String, echo: JsonElement = EmptyJsonString): String {
return if(GroupSvc.modifyGroupRemark(groupId.toLong(), remark)) return if(GroupSvc.modifyGroupRemark(groupId, remark))
ok("成功", echo) ok("成功", echo)
else error("check if member or group exist", echo) else error("check if member or group exist", echo)
} }

View File

@ -10,13 +10,13 @@ import moe.fuqiuluo.symbols.OneBotHandler
@OneBotHandler("rename_group_folder") @OneBotHandler("rename_group_folder")
internal object RenameGroupFolder: IActionHandler() { internal object RenameGroupFolder: IActionHandler() {
override suspend fun internalHandle(session: ActionSession): String { override suspend fun internalHandle(session: ActionSession): String {
val groupId = session.getString("group_id") val groupId = session.getLong("group_id")
val folderId = session.getString("folder_id") val folderId = session.getString("folder_id")
val name = session.getString("name") val name = session.getString("name")
return invoke(groupId, folderId, name, session.echo) return invoke(groupId, folderId, name, session.echo)
} }
suspend operator fun invoke(groupId: String, folderId: String, name: String, echo: JsonElement = EmptyJsonString): String { suspend operator fun invoke(groupId: Long, folderId: String, name: String, echo: JsonElement = EmptyJsonString): String {
if (!FileSvc.renameFolder(groupId, folderId, name)) { if (!FileSvc.renameFolder(groupId, folderId, name)) {
return error("rename folder failed", echo = echo) return error("rename folder failed", echo = echo)
} }

View File

@ -39,27 +39,27 @@ internal object SendForwardMessage : IActionHandler() {
} }
} }
val peerId = when (chatType) { val peerId = when (chatType) {
MsgConstant.KCHATTYPEGROUP -> session.getStringOrNull("group_id") ?: return noParam( MsgConstant.KCHATTYPEGROUP -> session.getLongOrNull("group_id") ?: return noParam(
"group_id", "group_id",
session.echo session.echo
) )
MsgConstant.KCHATTYPEC2C, MsgConstant.KCHATTYPETEMPC2CFROMGROUP -> session.getStringOrNull("user_id") MsgConstant.KCHATTYPEC2C, MsgConstant.KCHATTYPETEMPC2CFROMGROUP -> session.getLongOrNull("user_id")
?: return noParam("user_id", session.echo) ?: return noParam("user_id", session.echo)
else -> error("unknown chat type: $chatType") else -> error("unknown chat type: $chatType")
} }.toString()
val fromId = when (chatType) { val fromId = when (chatType) {
MsgConstant.KCHATTYPEGROUP, MsgConstant.KCHATTYPETEMPC2CFROMGROUP -> session.getStringOrNull("group_id") MsgConstant.KCHATTYPEGROUP, MsgConstant.KCHATTYPETEMPC2CFROMGROUP -> session.getLongOrNull("group_id")
?: return noParam("group_id", session.echo) ?: return noParam("group_id", session.echo)
MsgConstant.KCHATTYPEC2C -> session.getStringOrNull("user_id") ?: return noParam( MsgConstant.KCHATTYPEC2C -> session.getLongOrNull("user_id") ?: return noParam(
"user_id", "user_id",
session.echo session.echo
) )
else -> error("unknown chat type: $chatType") else -> error("unknown chat type: $chatType")
} }.toString()
return if (session.isArray("messages")) { return if (session.isArray("messages")) {
val messages = session.getArray("messages") val messages = session.getArray("messages")
invoke(chatType, peerId, messages, fromId, echo = session.echo) invoke(chatType, peerId, messages, fromId, echo = session.echo)

View File

@ -8,10 +8,10 @@ import moe.fuqiuluo.symbols.OneBotHandler
@OneBotHandler("send_group_forward_msg") @OneBotHandler("send_group_forward_msg")
internal object SendGroupForwardMessage: IActionHandler() { internal object SendGroupForwardMessage: IActionHandler() {
override suspend fun internalHandle(session: ActionSession): String { override suspend fun internalHandle(session: ActionSession): String {
val groupId = session.getString("group_id") val groupId = session.getLong("group_id")
return if (session.isArray("messages")) { return if (session.isArray("messages")) {
val messages = session.getArray("messages") val messages = session.getArray("messages")
SendForwardMessage(MsgConstant.KCHATTYPEGROUP, groupId, messages, echo = session.echo) SendForwardMessage(MsgConstant.KCHATTYPEGROUP, groupId.toString(), messages, echo = session.echo)
} else { } else {
logic("未知格式合并转发消息", session.echo) logic("未知格式合并转发消息", session.echo)
} }

View File

@ -9,19 +9,19 @@ import moe.fuqiuluo.symbols.OneBotHandler
@OneBotHandler("send_group_message", ["send_group_msg"]) @OneBotHandler("send_group_message", ["send_group_msg"])
internal object SendGroupMessage: IActionHandler() { internal object SendGroupMessage: IActionHandler() {
override suspend fun internalHandle(session: ActionSession): String { override suspend fun internalHandle(session: ActionSession): String {
val groupId = session.getString("group_id") val groupId = session.getLong("group_id")
val retryCnt = session.getIntOrNull("retry_cnt") val retryCnt = session.getIntOrNull("retry_cnt")
val recallDuration = session.getLongOrNull("recall_duration") val recallDuration = session.getLongOrNull("recall_duration")
return if (session.isString("message")) { return if (session.isString("message")) {
val autoEscape = session.getBooleanOrDefault("auto_escape", false) val autoEscape = session.getBooleanOrDefault("auto_escape", false)
val message = session.getString("message") val message = session.getString("message")
SendMessage(MsgConstant.KCHATTYPEGROUP, groupId, message, autoEscape, echo = session.echo, retryCnt = retryCnt ?: 3, recallDuration = recallDuration) SendMessage(MsgConstant.KCHATTYPEGROUP, groupId.toString(), message, autoEscape, echo = session.echo, retryCnt = retryCnt ?: 3, recallDuration = recallDuration)
} else if (session.isObject("message")) { } else if (session.isObject("message")) {
val message = session.getObject("message") val message = session.getObject("message")
SendMessage(MsgConstant.KCHATTYPEGROUP, groupId, listOf( message ).jsonArray, session.echo, retryCnt = retryCnt ?: 3, recallDuration = recallDuration) SendMessage(MsgConstant.KCHATTYPEGROUP, groupId.toString(), listOf( message ).jsonArray, session.echo, retryCnt = retryCnt ?: 3, recallDuration = recallDuration)
} else { } else {
val message = session.getArray("message") val message = session.getArray("message")
SendMessage(MsgConstant.KCHATTYPEGROUP, groupId, message, session.echo, retryCnt = retryCnt ?: 3, recallDuration = recallDuration) SendMessage(MsgConstant.KCHATTYPEGROUP, groupId.toString(), message, session.echo, retryCnt = retryCnt ?: 3, recallDuration = recallDuration)
} }
} }

View File

@ -41,15 +41,15 @@ internal object SendMessage: IActionHandler() {
} }
} }
val peerId = when(chatType) { val peerId = when(chatType) {
MsgConstant.KCHATTYPEGROUP -> session.getStringOrNull("group_id") ?: return noParam("group_id", session.echo) MsgConstant.KCHATTYPEGROUP -> session.getLongOrNull("group_id") ?: return noParam("group_id", session.echo)
MsgConstant.KCHATTYPEC2C, MsgConstant.KCHATTYPETEMPC2CFROMGROUP -> session.getStringOrNull("user_id") ?: return noParam("user_id", session.echo) MsgConstant.KCHATTYPEC2C, MsgConstant.KCHATTYPETEMPC2CFROMGROUP -> session.getLongOrNull("user_id") ?: return noParam("user_id", session.echo)
else -> error("unknown chat type: $chatType") else -> error("unknown chat type: $chatType")
} }.toString()
val fromId = when(chatType) { val fromId = when(chatType) {
MsgConstant.KCHATTYPEGROUP, MsgConstant.KCHATTYPETEMPC2CFROMGROUP -> session.getStringOrNull("group_id") ?: return noParam("group_id", session.echo) MsgConstant.KCHATTYPEGROUP, MsgConstant.KCHATTYPETEMPC2CFROMGROUP -> session.getLongOrNull("group_id") ?: return noParam("group_id", session.echo)
MsgConstant.KCHATTYPEC2C -> session.getStringOrNull("user_id") ?: return noParam("user_id", session.echo) MsgConstant.KCHATTYPEC2C -> session.getLongOrNull("user_id") ?: return noParam("user_id", session.echo)
else -> error("unknown chat type: $chatType") else -> error("unknown chat type: $chatType")
} }.toString()
val retryCnt = session.getIntOrNull("retry_cnt") val retryCnt = session.getIntOrNull("retry_cnt")
val recallDuration = session.getLongOrNull("recall_duration") val recallDuration = session.getLongOrNull("recall_duration")
return if (session.isString("message")) { return if (session.isString("message")) {

View File

@ -8,10 +8,10 @@ import moe.fuqiuluo.symbols.OneBotHandler
@OneBotHandler("send_private_forward_msg") @OneBotHandler("send_private_forward_msg")
internal object SendPrivateForwardMessage : IActionHandler() { internal object SendPrivateForwardMessage : IActionHandler() {
override suspend fun internalHandle(session: ActionSession): String { override suspend fun internalHandle(session: ActionSession): String {
val userId = session.getString("user_id") val userId = session.getLong("user_id")
return if (session.isArray("messages")) { return if (session.isArray("messages")) {
val messages = session.getArray("messages") val messages = session.getArray("messages")
SendForwardMessage(MsgConstant.KCHATTYPEC2C, userId, messages, echo = session.echo) SendForwardMessage(MsgConstant.KCHATTYPEC2C, userId.toString(), messages, echo = session.echo)
} else { } else {
logic("未知格式合并转发消息", session.echo) logic("未知格式合并转发消息", session.echo)
} }

View File

@ -7,45 +7,33 @@ import moe.fuqiuluo.shamrock.tools.jsonArray
import moe.fuqiuluo.symbols.OneBotHandler import moe.fuqiuluo.symbols.OneBotHandler
@OneBotHandler("send_private_msg", ["send_private_message"]) @OneBotHandler("send_private_msg", ["send_private_message"])
internal object SendPrivateMessage: IActionHandler() { internal object SendPrivateMessage : IActionHandler() {
override suspend fun internalHandle(session: ActionSession): String { override suspend fun internalHandle(session: ActionSession): String {
val userId = session.getString("user_id") val userId = session.getLong("user_id")
val groupId = session.getStringOrNull("group_id") val groupId = session.getLongOrNull("group_id")
val chatType = if (groupId == null) MsgConstant.KCHATTYPEC2C else MsgConstant.KCHATTYPETEMPC2CFROMGROUP val chatType = if (groupId == null) MsgConstant.KCHATTYPEC2C else MsgConstant.KCHATTYPETEMPC2CFROMGROUP
val retryCnt = session.getIntOrNull("retry_cnt") val retryCnt = session.getIntOrNull("retry_cnt")
val recallDuration = session.getLongOrNull("recall_duration") val recallDuration = session.getLongOrNull("recall_duration")
return if (session.isString("message")) { return if (session.isString("message")) {
val autoEscape = session.getBooleanOrDefault("auto_escape", false) val autoEscape = session.getBooleanOrDefault("auto_escape", false)
val message = session.getString("message") val message = session.getString("message")
SendMessage.invoke( SendMessage(
chatType = chatType, chatType = chatType,
peerId = userId, peerId = userId.toString(),
message = message, message = message,
autoEscape = autoEscape, autoEscape = autoEscape,
echo = session.echo, echo = session.echo,
fromId = groupId ?: userId, fromId = groupId?.toString() ?: userId.toString(),
retryCnt = retryCnt ?: 3,
recallDuration = recallDuration
)
} else if (session.isArray("message")) {
val message = session.getArray("message")
SendMessage(
chatType = chatType,
peerId = userId,
message = message,
echo = session.echo,
fromId = groupId ?: userId,
retryCnt = retryCnt ?: 3, retryCnt = retryCnt ?: 3,
recallDuration = recallDuration recallDuration = recallDuration
) )
} else { } else {
val message = session.getObject("message")
SendMessage( SendMessage(
chatType = chatType, chatType = chatType,
peerId = userId, peerId = userId.toString(),
message = listOf( message ).jsonArray, message = if (session.isArray("message")) session.getArray("message") else listOf(session.getObject("message")).jsonArray,
echo = session.echo, echo = session.echo,
fromId = groupId ?: userId, fromId = groupId?.toString() ?: userId.toString(),
retryCnt = retryCnt ?: 3, retryCnt = retryCnt ?: 3,
recallDuration = recallDuration recallDuration = recallDuration
) )

View File

@ -17,7 +17,7 @@ internal object SetGroupAdmin: IActionHandler() {
} }
operator fun invoke(groupId: Long, userId: Long, enable: Boolean, echo: JsonElement = EmptyJsonString): String { operator fun invoke(groupId: Long, userId: Long, enable: Boolean, echo: JsonElement = EmptyJsonString): String {
if (!GroupSvc.isOwner(groupId.toString())) { if (!GroupSvc.isOwner(groupId)) {
return logic("you are not owner", echo) return logic("you are not owner", echo)
} }
GroupSvc.setGroupAdmin(groupId, userId, enable) GroupSvc.setGroupAdmin(groupId, userId, enable)

View File

@ -10,13 +10,13 @@ import moe.fuqiuluo.symbols.OneBotHandler
@OneBotHandler("set_group_special_title") @OneBotHandler("set_group_special_title")
internal object SetGroupUnique: IActionHandler() { internal object SetGroupUnique: IActionHandler() {
override suspend fun internalHandle(session: ActionSession): String { override suspend fun internalHandle(session: ActionSession): String {
val groupId = session.getString("group_id") val groupId = session.getLong("group_id")
val userId = session.getString("user_id") val userId = session.getLong("user_id")
val unique = session.getString("special_title") val unique = session.getString("special_title")
return invoke(groupId, userId, unique, session.echo) return invoke(groupId, userId, unique, session.echo)
} }
suspend operator fun invoke(groupId: String, userId: String, unique: String, echo: JsonElement = EmptyJsonString): String { suspend operator fun invoke(groupId: Long, userId: Long, unique: String, echo: JsonElement = EmptyJsonString): String {
if (!GroupSvc.isOwner(groupId)) { if (!GroupSvc.isOwner(groupId)) {
return error("you are not owner", echo) return error("you are not owner", echo)
} }

View File

@ -15,7 +15,7 @@ internal object SetGuildMemberRole: IActionHandler() {
val role = session.getString("role_id").toULong() val role = session.getString("role_id").toULong()
val set = session.getBooleanOrDefault("set", false) val set = session.getBooleanOrDefault("set", false)
return if (session.has("user_id")) { return if (session.has("user_id")) {
val userId = session.getString("user_id").toULong() val userId = session.getLong("user_id").toULong()
invoke(guildId, userId, role, set, echo = session.echo) invoke(guildId, userId, role, set, echo = session.echo)
} else if (session.isArray("users")) { } else if (session.isArray("users")) {
invoke(guildId, session.getArray("users").map { invoke(guildId, session.getArray("users").map {

View File

@ -11,15 +11,15 @@ import mqq.app.MobileQQ
@OneBotHandler("switch_account") @OneBotHandler("switch_account")
internal object SwitchAccount: IActionHandler() { internal object SwitchAccount: IActionHandler() {
override suspend fun internalHandle(session: ActionSession): String { override suspend fun internalHandle(session: ActionSession): String {
val userId = session.getString("user_id") val userId = session.getLong("user_id")
return invoke(userId, session.echo) return invoke(userId, session.echo)
} }
operator fun invoke( operator fun invoke(
userId: String, userId: Long,
echo: JsonElement = EmptyJsonString echo: JsonElement = EmptyJsonString
): String { ): String {
val account = MobileQQ.getMobileQQ().allAccounts.firstOrNull { it.uin == userId } val account = MobileQQ.getMobileQQ().allAccounts.firstOrNull { it.uin == userId.toString() }
?: return error("账号不存在", echo) ?: return error("账号不存在", echo)
val runtime = AppRuntimeFetcher.appRuntime val runtime = AppRuntimeFetcher.appRuntime
val result = kotlin.runCatching { val result = kotlin.runCatching {

View File

@ -34,7 +34,7 @@ import kotlin.coroutines.resume
@OneBotHandler("upload_group_file") @OneBotHandler("upload_group_file")
internal object UploadGroupFile : IActionHandler() { internal object UploadGroupFile : IActionHandler() {
override suspend fun internalHandle(session: ActionSession): String { override suspend fun internalHandle(session: ActionSession): String {
val groupId = session.getString("group_id") val groupId = session.getLong("group_id")
val file = session.getString("file") val file = session.getString("file")
val name = session.getString("name") val name = session.getString("name")
.replace("/", "_") .replace("/", "_")
@ -46,7 +46,7 @@ internal object UploadGroupFile : IActionHandler() {
} }
suspend operator fun invoke( suspend operator fun invoke(
groupId: String, groupId: Long,
file: String, file: String,
name: String, name: String,
echo: JsonElement = EmptyJsonString echo: JsonElement = EmptyJsonString
@ -105,7 +105,7 @@ internal object UploadGroupFile : IActionHandler() {
val msgIdPair = MessageHelper.generateMsgId(MsgConstant.KCHATTYPEGROUP) val msgIdPair = MessageHelper.generateMsgId(MsgConstant.KCHATTYPEGROUP)
val info = (withTimeoutOrNull((srcFile.length() / (125 * 1024)) * 1000 + 5000) { val info = (withTimeoutOrNull((srcFile.length() / (125 * 1024)) * 1000 + 5000) {
val msgService = QRoute.api(IMsgService::class.java) val msgService = QRoute.api(IMsgService::class.java)
val contact = MessageHelper.generateContact(MsgConstant.KCHATTYPEGROUP, groupId) val contact = MessageHelper.generateContact(MsgConstant.KCHATTYPEGROUP, groupId.toString())
suspendCancellableCoroutine<FileTransNotifyInfo?> { suspendCancellableCoroutine<FileTransNotifyInfo?> {
msgService.sendMsgWithMsgId( msgService.sendMsgWithMsgId(
contact, msgIdPair.qqMsgId, arrayListOf(msgElement) contact, msgIdPair.qqMsgId, arrayListOf(msgElement)

View File

@ -35,7 +35,7 @@ import kotlin.coroutines.resume
@OneBotHandler("upload_private_file") @OneBotHandler("upload_private_file")
internal object UploadPrivateFile : IActionHandler() { internal object UploadPrivateFile : IActionHandler() {
override suspend fun internalHandle(session: ActionSession): String { override suspend fun internalHandle(session: ActionSession): String {
val userId = session.getString("user_id") val userId = session.getLong("user_id")
val file = session.getString("file") val file = session.getString("file")
val name = session.getString("name") val name = session.getString("name")
.replace("/", "_") .replace("/", "_")
@ -47,7 +47,7 @@ internal object UploadPrivateFile : IActionHandler() {
} }
suspend operator fun invoke( suspend operator fun invoke(
userId: String, userId: Long,
file: String, file: String,
name: String, name: String,
echo: JsonElement = EmptyJsonString echo: JsonElement = EmptyJsonString
@ -106,7 +106,7 @@ internal object UploadPrivateFile : IActionHandler() {
val msgIdPair = MessageHelper.generateMsgId(MsgConstant.KCHATTYPEC2C) val msgIdPair = MessageHelper.generateMsgId(MsgConstant.KCHATTYPEC2C)
val info = (withTimeoutOrNull((srcFile.length() / (300 * 1024)) * 1000 + 5000) { val info = (withTimeoutOrNull((srcFile.length() / (300 * 1024)) * 1000 + 5000) {
val msgService = QRoute.api(IMsgService::class.java) val msgService = QRoute.api(IMsgService::class.java)
val contact = MessageHelper.generateContact(MsgConstant.KCHATTYPEC2C, userId) val contact = MessageHelper.generateContact(MsgConstant.KCHATTYPEC2C, userId.toString())
suspendCancellableCoroutine<FileTransNotifyInfo?> { suspendCancellableCoroutine<FileTransNotifyInfo?> {
msgService.sendMsgWithMsgId( msgService.sendMsgWithMsgId(
contact, msgIdPair.qqMsgId, arrayListOf(msgElement) contact, msgIdPair.qqMsgId, arrayListOf(msgElement)

View File

@ -18,8 +18,8 @@ import moe.fuqiuluo.shamrock.tools.getOrPost
fun Routing.friendAction() { fun Routing.friendAction() {
getOrPost("/get_stranger_info") { getOrPost("/get_stranger_info") {
val uin = fetchOrThrow("user_id") val userId = fetchOrThrow("user_id").toLong()
call.respondText(GetStrangerInfo(uin), ContentType.Application.Json) call.respondText(GetStrangerInfo(userId), ContentType.Application.Json)
} }
getOrPost("/get_friend_list") { getOrPost("/get_friend_list") {
@ -29,8 +29,8 @@ fun Routing.friendAction() {
} }
getOrPost("/is_blacklist_uin") { getOrPost("/is_blacklist_uin") {
val uin = fetchOrThrow("user_id") val userId = fetchOrThrow("user_id").toLong()
call.respondText(IsBlackListUin(uin), ContentType.Application.Json) call.respondText(IsBlackListUin(userId), ContentType.Application.Json)
} }
getOrPost("/get_friend_system_msg") { getOrPost("/get_friend_system_msg") {

View File

@ -26,7 +26,7 @@ fun Routing.troopAction() {
} }
getOrPost("/get_not_joined_group_info") { getOrPost("/get_not_joined_group_info") {
val groupId = fetchOrThrow("group_id") val groupId = fetchOrThrow("group_id").toLong()
call.respondText(GetNotJoinedGroupInfo(groupId), ContentType.Application.Json) call.respondText(GetNotJoinedGroupInfo(groupId), ContentType.Application.Json)
} }
@ -36,28 +36,28 @@ fun Routing.troopAction() {
} }
getOrPost("/group_touch") { getOrPost("/group_touch") {
val groupId = fetchOrThrow("group_id") val groupId = fetchOrThrow("group_id").toLong()
val userId = fetchOrThrow("user_id") val userId = fetchOrThrow("user_id").toLong()
call.respondText(GroupPoke(groupId, userId), ContentType.Application.Json) call.respondText(GroupPoke(groupId, userId), ContentType.Application.Json)
} }
getOrPost("/get_group_honor_info") { getOrPost("/get_group_honor_info") {
val groupId = fetchOrThrow("group_id") val groupId = fetchOrThrow("group_id").toLong()
val refresh = fetchOrNull("no_cache")?.toBooleanStrict() val refresh = fetchOrNull("no_cache")?.toBooleanStrict()
?: fetchOrNull("refresh")?.toBooleanStrict() ?: false ?: fetchOrNull("refresh")?.toBooleanStrict() ?: false
call.respondText(GetTroopHonor(groupId, refresh), ContentType.Application.Json) call.respondText(GetTroopHonor(groupId, refresh), ContentType.Application.Json)
} }
getOrPost("/get_group_member_list") { getOrPost("/get_group_member_list") {
val groupId = fetchOrThrow("group_id") val groupId = fetchOrThrow("group_id").toLong()
val refresh = fetchOrNull("no_cache")?.toBooleanStrict() val refresh = fetchOrNull("no_cache")?.toBooleanStrict()
?: fetchOrNull("refresh")?.toBooleanStrict() ?: false ?: fetchOrNull("refresh")?.toBooleanStrict() ?: false
call.respondText(GetTroopMemberList(groupId, refresh), ContentType.Application.Json) call.respondText(GetTroopMemberList(groupId, refresh), ContentType.Application.Json)
} }
getOrPost("/get_group_member_info") { getOrPost("/get_group_member_info") {
val groupId = fetchOrThrow("group_id") val groupId = fetchOrThrow("group_id").toLong()
val userId = fetchOrThrow("user_id") val userId = fetchOrThrow("user_id").toLong()
val refresh = fetchOrNull("no_cache")?.toBooleanStrict() val refresh = fetchOrNull("no_cache")?.toBooleanStrict()
?: fetchOrNull("refresh")?.toBooleanStrict() ?: false ?: fetchOrNull("refresh")?.toBooleanStrict() ?: false
call.respondText(GetTroopMemberInfo(groupId, userId, refresh), ContentType.Application.Json) call.respondText(GetTroopMemberInfo(groupId, userId, refresh), ContentType.Application.Json)
@ -70,48 +70,48 @@ fun Routing.troopAction() {
} }
getOrPost("/get_group_info") { getOrPost("/get_group_info") {
val groupId = fetchOrThrow("group_id") val groupId = fetchOrThrow("group_id").toLong()
val refresh = fetchOrNull("no_cache")?.toBooleanStrict() val refresh = fetchOrNull("no_cache")?.toBooleanStrict()
?: fetchOrNull("refresh")?.toBooleanStrict() ?: false ?: fetchOrNull("refresh")?.toBooleanStrict() ?: false
call.respondText(GetTroopInfo(groupId, refresh), ContentType.Application.Json) call.respondText(GetTroopInfo(groupId, refresh), ContentType.Application.Json)
} }
getOrPost("/set_group_special_title") { getOrPost("/set_group_special_title") {
val groupId = fetchOrThrow("group_id") val groupId = fetchOrThrow("group_id").toLong()
val userId = fetchOrThrow("user_id") val userId = fetchOrThrow("user_id").toLong()
val title = fetchOrThrow("special_title") val title = fetchOrThrow("special_title")
call.respondText(SetGroupUnique(groupId, userId, title), ContentType.Application.Json) call.respondText(SetGroupUnique(groupId, userId, title), ContentType.Application.Json)
} }
getOrPost("/set_group_name") { getOrPost("/set_group_name") {
val groupId = fetchOrThrow("group_id") val groupId = fetchOrThrow("group_id").toLong()
val card = fetchOrThrow("group_name") val card = fetchOrThrow("group_name")
call.respondText(ModifyTroopName(groupId, card), ContentType.Application.Json) call.respondText(ModifyTroopName(groupId, card), ContentType.Application.Json)
} }
getOrPost("/set_group_card") { getOrPost("/set_group_card") {
val groupId = fetchOrThrow("group_id") val groupId = fetchOrThrow("group_id").toLong()
val userId = fetchOrThrow("user_id") val userId = fetchOrThrow("user_id").toLong()
val card = fetchOrNull("card") ?: "" val card = fetchOrNull("card") ?: ""
call.respondText(ModifyTroopMemberName(groupId, userId, card), ContentType.Application.Json) call.respondText(ModifyTroopMemberName(groupId, userId, card), ContentType.Application.Json)
} }
getOrPost("/set_group_admin") { getOrPost("/set_group_admin") {
val groupId = fetchOrThrow("group_id") .toLong() val groupId = fetchOrThrow("group_id").toLong()
val userId = fetchOrThrow("user_id") .toLong() val userId = fetchOrThrow("user_id").toLong()
val enable = fetchOrThrow("enable").toBooleanStrict() val enable = fetchOrThrow("enable").toBooleanStrict()
call.respondText(SetGroupAdmin(groupId, userId, enable), ContentType.Application.Json) call.respondText(SetGroupAdmin(groupId, userId, enable), ContentType.Application.Json)
} }
getOrPost("/set_group_whole_ban") { getOrPost("/set_group_whole_ban") {
val groupId = fetchOrThrow("group_id") .toLong() val groupId = fetchOrThrow("group_id").toLong()
val enable = fetchOrThrow("enable").toBooleanStrict() val enable = fetchOrThrow("enable").toBooleanStrict()
call.respondText(SetGroupWholeBan(groupId, enable), ContentType.Application.Json) call.respondText(SetGroupWholeBan(groupId, enable), ContentType.Application.Json)
} }
getOrPost("/set_group_ban") { getOrPost("/set_group_ban") {
val groupId = fetchOrThrow("group_id") .toLong() val groupId = fetchOrThrow("group_id").toLong()
val userId = fetchOrThrow("user_id") .toLong() val userId = fetchOrThrow("user_id").toLong()
val duration = fetchOrNull("duration")?.toInt() ?: (30 * 60) val duration = fetchOrNull("duration")?.toInt() ?: (30 * 60)
call.respondText(BanTroopMember(groupId, userId, duration), ContentType.Application.Json) call.respondText(BanTroopMember(groupId, userId, duration), ContentType.Application.Json)

View File

@ -48,7 +48,10 @@ fun Routing.messageAction() {
post { post {
val groupId = fetchPostOrNull("group_id") val groupId = fetchPostOrNull("group_id")
val messages = fetchPostJsonArray("messages") val messages = fetchPostJsonArray("messages")
call.respondText(SendForwardMessage(MsgConstant.KCHATTYPEGROUP, groupId ?: "", messages), ContentType.Application.Json) call.respondText(
SendForwardMessage(MsgConstant.KCHATTYPEGROUP, groupId ?: "", messages),
ContentType.Application.Json
)
} }
get { get {
respond(false, Status.InternalHandlerError, "Not support GET method") respond(false, Status.InternalHandlerError, "Not support GET method")
@ -59,7 +62,10 @@ fun Routing.messageAction() {
post { post {
val userId = fetchPostOrNull("user_id") val userId = fetchPostOrNull("user_id")
val messages = fetchPostJsonArray("messages") val messages = fetchPostJsonArray("messages")
call.respondText(SendForwardMessage(MsgConstant.KCHATTYPEC2C, userId ?: "", messages), ContentType.Application.Json) call.respondText(
SendForwardMessage(MsgConstant.KCHATTYPEC2C, userId ?: "", messages),
ContentType.Application.Json
)
} }
get { get {
respond(false, Status.InternalHandlerError, "Not support GET method") respond(false, Status.InternalHandlerError, "Not support GET method")
@ -71,7 +77,10 @@ fun Routing.messageAction() {
val userId = fetchPostOrNull("user_id") val userId = fetchPostOrNull("user_id")
val groupId = fetchPostOrNull("group_id") val groupId = fetchPostOrNull("group_id")
val messages = fetchPostJsonArray("messages") val messages = fetchPostJsonArray("messages")
call.respondText(SendForwardMessage(MsgConstant.KCHATTYPEC2C, userId ?: groupId?: "", messages), ContentType.Application.Json) call.respondText(
SendForwardMessage(MsgConstant.KCHATTYPEC2C, userId ?: groupId ?: "", messages),
ContentType.Application.Json
)
} }
get { get {
respond(false, Status.InternalHandlerError, "Not support GET method") respond(false, Status.InternalHandlerError, "Not support GET method")
@ -137,15 +146,17 @@ fun Routing.messageAction() {
val recallDuration = fetchGetOrNull("recall_duration")?.toLongOrNull() val recallDuration = fetchGetOrNull("recall_duration")?.toLongOrNull()
call.respondText(SendMessage( call.respondText(
chatType = chatType, SendMessage(
peerId = if (chatType == MsgConstant.KCHATTYPEC2C) userId!! else groupId!!, chatType = chatType,
message = message, peerId = if (chatType == MsgConstant.KCHATTYPEC2C) userId!! else groupId!!,
autoEscape = autoEscape, message = message,
fromId = groupId ?: userId ?: "", autoEscape = autoEscape,
retryCnt = retryCnt, fromId = groupId ?: userId ?: "",
recallDuration = recallDuration retryCnt = retryCnt,
), ContentType.Application.Json) recallDuration = recallDuration
), ContentType.Application.Json
)
} }
post { post {
val msgType = fetchPostOrThrow("message_type") val msgType = fetchPostOrThrow("message_type")
@ -157,39 +168,30 @@ fun Routing.messageAction() {
val peerId = if (chatType == MsgConstant.KCHATTYPEC2C) userId!! else groupId!! val peerId = if (chatType == MsgConstant.KCHATTYPEC2C) userId!! else groupId!!
val recallDuration = fetchPostOrNull("recall_duration")?.toLongOrNull() val recallDuration = fetchPostOrNull("recall_duration")?.toLongOrNull()
call.respondText(if (isJsonData() && !isJsonString("message")) { call.respondText(
if (isJsonObject("message")) { if (isJsonData() && !isJsonString("message")) {
SendMessage( SendMessage(
chatType = chatType, chatType = chatType,
peerId = peerId, peerId = peerId,
message = listOf(fetchPostJsonObject("message")).jsonArray, message = if (isJsonObject("message")) listOf(fetchPostJsonObject("message")).jsonArray else fetchPostJsonArray("message"),
fromId = groupId ?: userId ?: "", fromId = groupId ?: userId ?: "",
retryCnt = retryCnt, retryCnt = retryCnt,
recallDuration = recallDuration recallDuration = recallDuration
) )
} else { } else {
val autoEscape = fetchPostOrNull("auto_escape")?.toBooleanStrict() ?: false
//SendMessage(chatType, peerId, fetchPostOrThrow("message"), autoEscape)
SendMessage( SendMessage(
chatType = chatType, chatType = chatType,
peerId = peerId, peerId = peerId,
message = fetchPostJsonArray("message"), message = fetchPostOrThrow("message"),
autoEscape = autoEscape,
fromId = groupId ?: userId ?: "", fromId = groupId ?: userId ?: "",
retryCnt = retryCnt, retryCnt = retryCnt,
recallDuration = recallDuration recallDuration = recallDuration
) )
} }, ContentType.Application.Json
} else { )
val autoEscape = fetchPostOrNull("auto_escape")?.toBooleanStrict() ?: false
//SendMessage(chatType, peerId, fetchPostOrThrow("message"), autoEscape)
SendMessage(
chatType = chatType,
peerId = peerId,
message = fetchPostOrThrow("message"),
autoEscape = autoEscape,
fromId = groupId ?: userId ?: "",
retryCnt = retryCnt,
recallDuration = recallDuration
)
}, ContentType.Application.Json)
} }
} }
@ -201,7 +203,16 @@ fun Routing.messageAction() {
val autoEscape = fetchGetOrNull("auto_escape")?.toBooleanStrict() ?: false val autoEscape = fetchGetOrNull("auto_escape")?.toBooleanStrict() ?: false
val recallDuration = fetchGetOrNull("recall_duration")?.toLongOrNull() val recallDuration = fetchGetOrNull("recall_duration")?.toLongOrNull()
call.respondText(SendMessage(MsgConstant.KCHATTYPEGROUP, groupId, message, autoEscape, retryCnt = retryCnt, recallDuration = recallDuration), ContentType.Application.Json) call.respondText(
SendMessage(
MsgConstant.KCHATTYPEGROUP,
groupId,
message,
autoEscape,
retryCnt = retryCnt,
recallDuration = recallDuration
), ContentType.Application.Json
)
} }
post { post {
val groupId = fetchPostOrThrow("group_id") val groupId = fetchPostOrThrow("group_id")
@ -212,28 +223,32 @@ fun Routing.messageAction() {
val result = if (isJsonData()) { val result = if (isJsonData()) {
if (isJsonString("message")) { if (isJsonString("message")) {
SendMessage(MsgConstant.KCHATTYPEGROUP, groupId, fetchPostJsonString("message"), autoEscape, retryCnt = retryCnt, recallDuration = recallDuration) SendMessage(
MsgConstant.KCHATTYPEGROUP,
groupId,
fetchPostJsonString("message"),
autoEscape,
retryCnt = retryCnt,
recallDuration = recallDuration
)
} else { } else {
if (isJsonObject("message")) { SendMessage(
SendMessage( chatType = MsgConstant.KCHATTYPEGROUP,
chatType = MsgConstant.KCHATTYPEGROUP, peerId = groupId,
peerId = groupId, message = if (isJsonObject("message")) listOf(fetchPostJsonObject("message")).jsonArray else fetchPostJsonArray("message"),
message = listOf(fetchPostJsonObject("message")).jsonArray, retryCnt = retryCnt,
retryCnt = retryCnt, recallDuration = recallDuration
recallDuration = recallDuration )
)
} else {
SendMessage(
chatType = MsgConstant.KCHATTYPEGROUP,
peerId = groupId,
message = fetchPostJsonArray("message"),
retryCnt = retryCnt,
recallDuration = recallDuration
)
}
} }
} else { } else {
SendMessage(MsgConstant.KCHATTYPEGROUP, groupId, fetchPostOrThrow("message"), autoEscape, retryCnt = retryCnt, recallDuration = recallDuration) SendMessage(
MsgConstant.KCHATTYPEGROUP,
groupId,
fetchPostOrThrow("message"),
autoEscape,
retryCnt = retryCnt,
recallDuration = recallDuration
)
} }
call.respondText(result, ContentType.Application.Json) call.respondText(result, ContentType.Application.Json)
@ -248,14 +263,16 @@ fun Routing.messageAction() {
val retryCnt = fetchGetOrNull("retry_cnt")?.toInt() ?: 3 val retryCnt = fetchGetOrNull("retry_cnt")?.toInt() ?: 3
val autoEscape = fetchGetOrNull("auto_escape")?.toBooleanStrict() ?: false val autoEscape = fetchGetOrNull("auto_escape")?.toBooleanStrict() ?: false
val recallDuration = fetchGetOrNull("recall_duration")?.toLongOrNull() val recallDuration = fetchGetOrNull("recall_duration")?.toLongOrNull()
call.respondText(SendMessage( call.respondText(
chatType = if (groupId == null) MsgConstant.KCHATTYPEC2C else MsgConstant.KCHATTYPETEMPC2CFROMGROUP, SendMessage(
peerId = userId, chatType = if (groupId == null) MsgConstant.KCHATTYPEC2C else MsgConstant.KCHATTYPETEMPC2CFROMGROUP,
message = message, peerId = userId,
autoEscape = autoEscape, message = message,
fromId = groupId ?: userId, autoEscape = autoEscape,
retryCnt = retryCnt, recallDuration = recallDuration fromId = groupId ?: userId,
), ContentType.Application.Json) retryCnt = retryCnt, recallDuration = recallDuration
), ContentType.Application.Json
)
} }
post { post {
val userId = fetchPostOrThrow("user_id") val userId = fetchPostOrThrow("user_id")
@ -278,23 +295,14 @@ fun Routing.messageAction() {
retryCnt = retryCnt, recallDuration = recallDuration retryCnt = retryCnt, recallDuration = recallDuration
) )
} else { } else {
if (isJsonObject("message")) { SendMessage(
SendMessage( chatType = chatType,
chatType = chatType, peerId = userId,
peerId = userId, message = if (isJsonObject("message")) listOf(fetchPostJsonObject("message")).jsonArray else fetchPostJsonArray("message"),
message = listOf(fetchPostJsonObject("message")).jsonArray, fromId = groupId ?: userId ?: "",
fromId = fromId, retryCnt = retryCnt,
retryCnt = retryCnt, recallDuration = recallDuration recallDuration = recallDuration
) )
} else {
SendMessage(
chatType = chatType,
peerId = userId,
message = fetchPostJsonArray("message"),
fromId = fromId,
retryCnt = retryCnt, recallDuration = recallDuration
)
}
} }
} else { } else {
SendMessage( SendMessage(

View File

@ -32,56 +32,56 @@ fun Routing.fetchRes() {
} }
getOrPost("/upload_group_file") { getOrPost("/upload_group_file") {
val groupId = fetchOrThrow("group_id") val groupId = fetchOrThrow("group_id").toLong()
val file = fetchOrThrow("file") val file = fetchOrThrow("file")
val name = fetchOrThrow("name") val name = fetchOrThrow("name")
call.respondText(UploadGroupFile(groupId, file, name), ContentType.Application.Json) call.respondText(UploadGroupFile(groupId, file, name), ContentType.Application.Json)
} }
getOrPost("/upload_private_file") { getOrPost("/upload_private_file") {
val userId = fetchOrThrow("user_id") val userId = fetchOrThrow("user_id").toLong()
val file = fetchOrThrow("file") val file = fetchOrThrow("file")
val name = fetchOrThrow("name") val name = fetchOrThrow("name")
call.respondText(UploadPrivateFile(userId, file, name), ContentType.Application.Json) call.respondText(UploadPrivateFile(userId, file, name), ContentType.Application.Json)
} }
getOrPost("/create_group_file_folder") { getOrPost("/create_group_file_folder") {
val groupId = fetchOrThrow("group_id") val groupId = fetchOrThrow("group_id").toLong()
val name = fetchOrThrow("name") val name = fetchOrThrow("name")
call.respondText(CreateGroupFileFolder(groupId, name), ContentType.Application.Json) call.respondText(CreateGroupFileFolder(groupId, name), ContentType.Application.Json)
} }
getOrPost("/delete_group_folder") { getOrPost("/delete_group_folder") {
val groupId = fetchOrThrow("group_id") val groupId = fetchOrThrow("group_id").toLong()
val id = fetchOrThrow("folder_id") val id = fetchOrThrow("folder_id")
call.respondText(DeleteGroupFolder(groupId, id), ContentType.Application.Json) call.respondText(DeleteGroupFolder(groupId, id), ContentType.Application.Json)
} }
getOrPost("/delete_group_file") { getOrPost("/delete_group_file") {
val groupId = fetchOrThrow("group_id") val groupId = fetchOrThrow("group_id").toLong()
val id = fetchOrThrow("file_id") val id = fetchOrThrow("file_id")
val busid = fetchOrThrow("busid").toInt() val busid = fetchOrThrow("busid").toInt()
call.respondText(DeleteGroupFile(groupId, id, busid), ContentType.Application.Json) call.respondText(DeleteGroupFile(groupId, id, busid), ContentType.Application.Json)
} }
getOrPost("/get_group_file_system_info") { getOrPost("/get_group_file_system_info") {
val groupId = fetchOrThrow("group_id") val groupId = fetchOrThrow("group_id").toLong()
call.respondText(GetGroupFileSystemInfo(groupId), ContentType.Application.Json) call.respondText(GetGroupFileSystemInfo(groupId), ContentType.Application.Json)
} }
getOrPost("/get_group_root_files") { getOrPost("/get_group_root_files") {
val groupId = fetchOrThrow("group_id") val groupId = fetchOrThrow("group_id").toLong()
call.respondText(GetGroupRootFiles(groupId), ContentType.Application.Json) call.respondText(GetGroupRootFiles(groupId), ContentType.Application.Json)
} }
getOrPost("/get_group_files_by_folder") { getOrPost("/get_group_files_by_folder") {
val groupId = fetchOrThrow("group_id") val groupId = fetchOrThrow("group_id").toLong()
val folderId = fetchOrThrow("folder_id") val folderId = fetchOrThrow("folder_id")
call.respondText(GetGroupSubFiles(groupId, folderId), ContentType.Application.Json) call.respondText(GetGroupSubFiles(groupId, folderId), ContentType.Application.Json)
} }
getOrPost("/get_group_file_url") { getOrPost("/get_group_file_url") {
val groupId = fetchOrThrow("group_id") val groupId = fetchOrThrow("group_id").toLong()
val id = fetchOrThrow("file_id") val id = fetchOrThrow("file_id")
val busid = fetchOrThrow("busid").toInt() val busid = fetchOrThrow("busid").toInt()
call.respondText(GetGroupFileUrl(groupId, id, busid), ContentType.Application.Json) call.respondText(GetGroupFileUrl(groupId, id, busid), ContentType.Application.Json)

View File

@ -13,13 +13,13 @@ import moe.fuqiuluo.shamrock.utils.PlatformUtils
fun Routing.userAction() { fun Routing.userAction() {
getOrPost("/switch_account") { getOrPost("/switch_account") {
val userId = fetchOrThrow("user_id") val userId = fetchOrThrow("user_id").toLong()
call.respondText(SwitchAccount(userId), ContentType.Application.Json) call.respondText(SwitchAccount(userId), ContentType.Application.Json)
} }
getOrPost("/set_group_leave") { getOrPost("/set_group_leave") {
val group = fetchOrThrow("group_id") val groupId = fetchOrThrow("group_id").toLong()
call.respondText(LeaveTroop(group), ContentType.Application.Json) call.respondText(LeaveTroop(groupId), ContentType.Application.Json)
} }
getOrPost("/_get_online_clients") { getOrPost("/_get_online_clients") {

View File

@ -119,7 +119,7 @@ internal object GlobalEventTransmitter: BaseSvc() {
val botUin = app.longAccountUin val botUin = app.longAccountUin
var nickName = record.sendNickName var nickName = record.sendNickName
if (nickName.isNullOrEmpty()) { if (nickName.isNullOrEmpty()) {
CardSvc.getProfileCard(record.senderUin.toString()).onSuccess { CardSvc.getProfileCard(record.senderUin).onSuccess {
nickName = it.strNick ?: record.peerName nickName = it.strNick ?: record.peerName
} }
} }
@ -167,7 +167,7 @@ internal object GlobalEventTransmitter: BaseSvc() {
val botUin = app.longAccountUin val botUin = app.longAccountUin
var nickName = record.sendNickName var nickName = record.sendNickName
if (nickName.isNullOrEmpty()) { if (nickName.isNullOrEmpty()) {
CardSvc.getProfileCard(record.senderUin.toString()).onSuccess { CardSvc.getProfileCard(record.senderUin).onSuccess {
nickName = it.strNick ?: record.peerName nickName = it.strNick ?: record.peerName
} }
} }

View File

@ -77,6 +77,7 @@ internal object ShamrockConfig {
putBoolean("shell", intent.getBooleanExtra("shell", false)) // 开启Shell接口 putBoolean("shell", intent.getBooleanExtra("shell", false)) // 开启Shell接口
putBoolean("enable_sync_msg_as_sent_msg", intent.getBooleanExtra("enable_sync_msg_as_sent_msg", false)) // 推送同步消息 putBoolean("enable_sync_msg_as_sent_msg", intent.getBooleanExtra("enable_sync_msg_as_sent_msg", false)) // 推送同步消息
putBoolean("forbid_useless_process", intent.getBooleanExtra("forbid_useless_process", false)) // 禁用QQ生成无用进程 putBoolean("forbid_useless_process", intent.getBooleanExtra("forbid_useless_process", false)) // 禁用QQ生成无用进程
putBoolean("enable_old_bdh", intent.getBooleanExtra("enable_old_bdh", false)) // 启用旧版BDH
} }
Config.defaultToken = intent.getStringExtra("token") Config.defaultToken = intent.getStringExtra("token")
Config.antiTrace = intent.getBooleanExtra("anti_qq_trace", true) Config.antiTrace = intent.getBooleanExtra("anti_qq_trace", true)
@ -175,6 +176,10 @@ internal object ShamrockConfig {
return mmkv.getBoolean("inject_packet", false) return mmkv.getBoolean("inject_packet", false)
} }
fun enableOldBDH(): Boolean {
return mmkv.getBoolean("enable_old_bdh", false)
}
fun isDebug(): Boolean { fun isDebug(): Boolean {
return mmkv.getBoolean("debug", false) return mmkv.getBoolean("debug", false)
} }

View File

@ -17,23 +17,14 @@ internal const val HONOR_ATMOSPHERE = 12
internal const val HONOR_GIFT = 13 internal const val HONOR_GIFT = 13
@Serializable @Serializable
internal data class GroupMemberHonor( data class GroupMemberHonor(
@SerialName("user_id") val userId: Long, @SerialName("user_id") val userId: Long,
@SerialName("nickname") var nick: String, @SerialName("nickname") var nick: String,
@SerialName("avatar") val avatar: String, @SerialName("avatar") val avatar: String,
@SerialName("day_count") val dayCount: Int, @SerialName("day_count") val dayCount: Int,
@SerialName("id") val id: Int, @SerialName("id") val id: Int,
@SerialName("description") val desc: String, @SerialName("description") val desc: String,
) { )
constructor(userId: String, nick: String, avatar: String, dayCount: Int, id: Int, desc: String) : this(
userId.toLong(),
nick,
avatar,
dayCount,
id,
desc,
)
}
@Serializable @Serializable
internal data class GroupAllHonor( internal data class GroupAllHonor(
@ -45,4 +36,4 @@ internal data class GroupAllHonor(
@SerialName("strong_newbie_list") val strongNewbieList: List<GroupMemberHonor>?, @SerialName("strong_newbie_list") val strongNewbieList: List<GroupMemberHonor>?,
@SerialName("emotion_list") val emotionList: List<GroupMemberHonor>?, @SerialName("emotion_list") val emotionList: List<GroupMemberHonor>?,
@SerialName("all") val all: List<GroupMemberHonor>?, @SerialName("all") val all: List<GroupMemberHonor>?,
) )

View File

@ -384,7 +384,7 @@ internal object PrimitiveListener {
val targetUid = event.memberUid val targetUid = event.memberUid
val type = event.type val type = event.type
GroupSvc.getGroupMemberList(groupCode.toString(), true).onFailure { GroupSvc.getGroupMemberList(groupCode, true).onFailure {
LogCenter.log("新成员加入刷新群成员列表失败: $groupCode", Level.WARN) LogCenter.log("新成员加入刷新群成员列表失败: $groupCode", Level.WARN)
}.onSuccess { }.onSuccess {
LogCenter.log("新成员加入刷新群成员列表成功,群成员数量: ${it.size}", Level.INFO) LogCenter.log("新成员加入刷新群成员列表成功,群成员数量: ${it.size}", Level.INFO)
@ -422,7 +422,7 @@ internal object PrimitiveListener {
val type = event.type val type = event.type
val operatorUid = event.operatorUid val operatorUid = event.operatorUid
GroupSvc.getGroupMemberList(groupCode.toString(), true).onFailure { GroupSvc.getGroupMemberList(groupCode, true).onFailure {
LogCenter.log("新成员加入刷新群成员列表失败: $groupCode", Level.WARN) LogCenter.log("新成员加入刷新群成员列表失败: $groupCode", Level.WARN)
}.onSuccess { }.onSuccess {
LogCenter.log("新成员加入刷新群成员列表成功,群成员数量: ${it.size}", Level.INFO) LogCenter.log("新成员加入刷新群成员列表成功,群成员数量: ${it.size}", Level.INFO)

View File

@ -46,16 +46,14 @@ val Collection<Any>.json: JsonArray
get() { get() {
val arrayList = arrayListOf<JsonElement>() val arrayList = arrayListOf<JsonElement>()
forEach { forEach {
if (it != null) { when (it) {
when (it) { is JsonElement -> arrayList.add(it)
is JsonElement -> arrayList.add(it) is Number -> arrayList.add(it.json)
is Number -> arrayList.add(it.json) is String -> arrayList.add(it.json)
is String -> arrayList.add(it.json) is Boolean -> arrayList.add(it.json)
is Boolean -> arrayList.add(it.json) is Map<*, *> -> arrayList.add((it as Map<String, Any>).json)
is Map<*, *> -> arrayList.add((it as Map<String, Any>).json) is Collection<*> -> arrayList.add((it as Collection<Any>).json)
is Collection<*> -> arrayList.add((it as Collection<Any>).json) else -> error("unknown array type: ${it::class.java}")
else -> error("unknown array type: ${it::class.java}")
}
} }
} }
return arrayList.jsonArray return arrayList.jsonArray

View File

@ -117,6 +117,9 @@ internal class HookWrapperCodec: IAction {
//from.serviceCmd = "ShamrockInjectedCmd_${from.serviceCmd}" //from.serviceCmd = "ShamrockInjectedCmd_${from.serviceCmd}"
from.setBusinessFail(1) from.setBusinessFail(1)
from.putWupBuffer(EMPTY_BYTE_ARRAY) from.putWupBuffer(EMPTY_BYTE_ARRAY)
} else if (from.serviceCmd.startsWith("trpc.o3.") && ShamrockConfig.isInjectPacket()) {
from.setBusinessFail(1)
from.putWupBuffer(EMPTY_BYTE_ARRAY)
} else { } else {
pushOnReceive(from) pushOnReceive(from)
} }