diff --git a/qqinterface/src/main/java/com/tencent/qqnt/kernel/nativeinterface/IGProFetchMemberRolesCallback.java b/qqinterface/src/main/java/com/tencent/qqnt/kernel/nativeinterface/IGProFetchMemberRolesCallback.java new file mode 100644 index 0000000..19ced8e --- /dev/null +++ b/qqinterface/src/main/java/com/tencent/qqnt/kernel/nativeinterface/IGProFetchMemberRolesCallback.java @@ -0,0 +1,7 @@ +package com.tencent.qqnt.kernel.nativeinterface; + +import java.util.ArrayList; + +public interface IGProFetchMemberRolesCallback { + void onFetchMemberRolesCallback(int code, String reason, ArrayList roles); +} diff --git a/qqinterface/src/main/java/com/tencent/qqnt/kernel/nativeinterface/IGProGetUserInfoCallback.java b/qqinterface/src/main/java/com/tencent/qqnt/kernel/nativeinterface/IGProGetUserInfoCallback.java index 03fe70f..28905d4 100644 --- a/qqinterface/src/main/java/com/tencent/qqnt/kernel/nativeinterface/IGProGetUserInfoCallback.java +++ b/qqinterface/src/main/java/com/tencent/qqnt/kernel/nativeinterface/IGProGetUserInfoCallback.java @@ -3,5 +3,5 @@ package com.tencent.qqnt.kernel.nativeinterface; import java.util.ArrayList; public interface IGProGetUserInfoCallback { - void onGetUserInfo(int i2, String str, ArrayList arrayList, ArrayList arrayList2); + void onGetUserInfo(int code, String reason, ArrayList userList, ArrayList tinyIdList); } diff --git a/qqinterface/src/main/java/com/tencent/qqnt/kernel/nativeinterface/IKernelGuildService.java b/qqinterface/src/main/java/com/tencent/qqnt/kernel/nativeinterface/IKernelGuildService.java index 42880d9..f103cd9 100644 --- a/qqinterface/src/main/java/com/tencent/qqnt/kernel/nativeinterface/IKernelGuildService.java +++ b/qqinterface/src/main/java/com/tencent/qqnt/kernel/nativeinterface/IKernelGuildService.java @@ -41,7 +41,11 @@ public interface IKernelGuildService { void refreshGuildInfoOnly(long j2, boolean z, int i2); - void fetchUserInfo(long j2, long j3, ArrayList tinyIdList, int i2, IGProGetUserInfoCallback iGProGetUserInfoCallback); + void fetchMemberRoles(long guildId, long channelId, long tinyId, int seq, IGProFetchMemberRolesCallback cb); + + void refreshGuildUserProfileInfo(long guildId, long tinyId, int seq); + + void fetchUserInfo(long guildId, long channelId, ArrayList tinyIdList, int seq, IGProGetUserInfoCallback cb); GProSimpleProfile getSimpleProfile(long guildId, long tinyId, int seq); diff --git a/xposed/src/main/java/moe/fuqiuluo/qqinterface/servlet/GProSvc.kt b/xposed/src/main/java/moe/fuqiuluo/qqinterface/servlet/GProSvc.kt index 13a9d16..6879457 100644 --- a/xposed/src/main/java/moe/fuqiuluo/qqinterface/servlet/GProSvc.kt +++ b/xposed/src/main/java/moe/fuqiuluo/qqinterface/servlet/GProSvc.kt @@ -3,6 +3,7 @@ package moe.fuqiuluo.qqinterface.servlet import com.tencent.mobileqq.qqguildsdk.api.IGPSService +import com.tencent.qqnt.kernel.nativeinterface.GProGuildRole import com.tencent.qqnt.kernel.nativeinterface.GProRoleMemberList import com.tencent.qqnt.kernel.nativeinterface.IGProFetchMemberListWithRoleCallback import kotlinx.coroutines.suspendCancellableCoroutine @@ -108,6 +109,7 @@ internal object GProSvc: BaseSvc() { result: ArrayList = arrayListOf() ): Result>> { val kernelGProService = NTServiceFetcher.kernelService.wrapperSession.guildService + val fetchGuildMemberListResult: Pair> = (withTimeoutOrNull(5000) { suspendCancellableCoroutine { kernelGProService.fetchMemberListWithRole(guildId.toLong(), 0, startIndex, roleIndex, count, 0) { code, reason, finish, nextIndex, nextRoleIdIndex, _, seq, roleList -> @@ -203,6 +205,21 @@ internal object GProSvc: BaseSvc() { } } + suspend fun fetchGuildMemberRoles(guildId: ULong, tinyId: ULong, refresh: Boolean = false): Result> { + val kernelGProService = NTServiceFetcher.kernelService.wrapperSession.guildService + if (refresh) { + kernelGProService.refreshGuildUserProfileInfo(guildId.toLong(), tinyId.toLong(), 1) + } + val result: ArrayList = withTimeoutOrNull(5000) { + suspendCancellableCoroutine { + kernelGProService.fetchMemberRoles(guildId.toLong(), 0, tinyId.toLong(), 2) { code, reason, roles -> + it.resume(roles) + } + } + } ?: return Result.failure(Exception("unable to fetch guild member roles")) + return Result.success(result) + } + fun getGuildList(refresh: Boolean = false, forceOldApi: Boolean): ArrayList { val kernelGProService = NTServiceFetcher.kernelService.wrapperSession.guildService if (refresh) { diff --git a/xposed/src/main/java/moe/fuqiuluo/shamrock/remote/action/handlers/GetGuildMemberProfile.kt b/xposed/src/main/java/moe/fuqiuluo/shamrock/remote/action/handlers/GetGuildMemberProfile.kt new file mode 100644 index 0000000..d0d9b6c --- /dev/null +++ b/xposed/src/main/java/moe/fuqiuluo/shamrock/remote/action/handlers/GetGuildMemberProfile.kt @@ -0,0 +1,78 @@ +package moe.fuqiuluo.shamrock.remote.action.handlers + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable +import kotlinx.serialization.json.JsonElement +import moe.fuqiuluo.qqinterface.servlet.GProSvc +import moe.fuqiuluo.shamrock.remote.action.ActionSession +import moe.fuqiuluo.shamrock.remote.action.IActionHandler +import moe.fuqiuluo.shamrock.tools.EmptyJsonString +import moe.fuqiuluo.shamrock.tools.ifNullOrEmpty +import moe.fuqiuluo.symbols.OneBotHandler + +@OneBotHandler("get_guild_member_profile") +internal object GetGuildMemberProfile: IActionHandler() { + override suspend fun internalHandle(session: ActionSession): String { + val guildId = session.getString("guild_id").toULong() + val userId = session.getString("user_id").toULong() + return invoke(guildId, userId, session.echo) + } + + suspend operator fun invoke(guildId: ULong, userId: ULong, echo: JsonElement = EmptyJsonString): String { + val userResult = GProSvc.getUserGuildInfo(guildId, userId).onFailure { + return error(it.message ?: "unable to fetch guild member info", echo) + }.getOrThrow() + val roles = GProSvc.fetchGuildMemberRoles(guildId, userId).onFailure { + return error(it.message ?: "unable to fetch guild member roles", echo) + }.getOrThrow() + + return ok(GetGuildMemberInfo( + tinyId = userResult.memberTinyid, + nickname = userResult.nickName ?: "", + avatarUrl = userResult.url ?: "", + joinTime = userResult.joinTime, + roles = roles.map { + RoleInfo( + roleId = it.roleId.toString(), + roleName = it.name.ifNullOrEmpty(it.levelDsc.ifNullOrEmpty(it.displayTagName ?: ""))!!, + color = it.color, + permission = it.rolePermissions.permissionList.map { + Permission( + rootId = it.rootId, + childIds = it.childIds ?: emptyList() + ) + }, + type = it.type, + displayName = it.displayTagName ?: "" + ) + } + ), echo = echo) + } + + override val requiredParams: Array = arrayOf("guild_id", "user_id") + + @Serializable + data class GetGuildMemberInfo( + @SerialName("tiny_id") val tinyId: ULong, + @SerialName("nickname") val nickname: String, + @SerialName("avatar_url") val avatarUrl: String, + @SerialName("join_time") val joinTime: ULong, + @SerialName("roles") val roles: List + ) + + @Serializable + data class RoleInfo( + @SerialName("role_id") val roleId: String, + @SerialName("role_name") val roleName: String, + @SerialName("color") val color: Long, + @SerialName("permission") val permission: List, + @SerialName("type") val type: Int, + @SerialName("display_name") val displayName: String + ) + + @Serializable + data class Permission( + @SerialName("root_id") val rootId: Int, + @SerialName("child_ids") val childIds: List + ) +} \ No newline at end of file diff --git a/xposed/src/main/java/moe/fuqiuluo/shamrock/remote/api/GuildAction.kt b/xposed/src/main/java/moe/fuqiuluo/shamrock/remote/api/GuildAction.kt index 745a3c1..e1e404c 100644 --- a/xposed/src/main/java/moe/fuqiuluo/shamrock/remote/api/GuildAction.kt +++ b/xposed/src/main/java/moe/fuqiuluo/shamrock/remote/api/GuildAction.kt @@ -7,6 +7,7 @@ import io.ktor.server.routing.Routing import moe.fuqiuluo.shamrock.remote.action.handlers.GetGProChannelList import moe.fuqiuluo.shamrock.remote.action.handlers.GetGuildList import moe.fuqiuluo.shamrock.remote.action.handlers.GetGuildMemberList +import moe.fuqiuluo.shamrock.remote.action.handlers.GetGuildMemberProfile import moe.fuqiuluo.shamrock.remote.action.handlers.GetGuildMetaByGuest import moe.fuqiuluo.shamrock.remote.action.handlers.GetGuildServiceProfile import moe.fuqiuluo.shamrock.tools.fetchGetOrNull @@ -40,4 +41,10 @@ fun Routing.guildAction() { val refresh = fetchGetOrNull("refresh") ?: fetchOrNull("no_cache") call.respondText(GetGProChannelList(guildId.toULong(), refresh?.toBoolean() ?: false), ContentType.Application.Json) } + + getOrPost("/get_guild_member_profile") { + val guildId = fetchOrThrow("guild_id") + val userId = fetchOrThrow("user_id") + call.respondText(GetGuildMemberProfile(guildId.toULong(), userId.toULong()), ContentType.Application.Json) + } } \ No newline at end of file