Shamrock: support /get_guild_roles

This commit is contained in:
白池 2024-02-03 05:45:25 +08:00
parent 2f61f6da00
commit 7952453137
9 changed files with 149 additions and 5 deletions

View File

@ -0,0 +1,7 @@
package com.tencent.qqnt.kernel.nativeinterface;
import java.util.ArrayList;
public interface IGProFetchChannelInvisibleRoleListCallback {
void onFetchChannelInvisibleRoleList(int code, String reason, ArrayList<GProGuildRole> roles);
}

View File

@ -0,0 +1,7 @@
package com.tencent.qqnt.kernel.nativeinterface;
import java.util.ArrayList;
public interface IGProFetchChannelLiveableRoleListCallback {
void onFetchChannelLiveableRoleList(int code, String reason, int seq, ArrayList<GProGuildRole> roles);
}

View File

@ -0,0 +1,7 @@
package com.tencent.qqnt.kernel.nativeinterface;
import java.util.ArrayList;
public interface IGProFetchRoleListPermissionCallback {
void onFetchRoleListPermissionCallback(int code, String msg, ArrayList<GProGuildRole> roles, ArrayList<GProGuildRole> lvRoles, ArrayList<Long> myRoles, long unused);
}

View File

@ -0,0 +1,7 @@
package com.tencent.qqnt.kernel.nativeinterface;
import java.util.ArrayList;
public interface IGProFetchRolePermissionCallback {
void onFetchRolePermissionCallback(int code, String msg, GProGuildRole role, GProRolePermission permission, ArrayList<GProRolePermissionDesc> permissionDescs, ArrayList<GProRolePermissionCategory> permissionCategories);
}

View File

@ -32,7 +32,7 @@ public interface IKernelGuildService {
//void fetchGuestGuildInfoWithChannelList(String guildId, String str2, int i2, int seq, String str3, //void fetchGuestGuildInfoWithChannelList(String guildId, String str2, int i2, int seq, String str3,
// IGProFetchGuestGuildInfoWithChannelListCallback iGProFetchGuestGuildInfoWithChannelListCallback); // IGProFetchGuestGuildInfoWithChannelListCallback iGProFetchGuestGuildInfoWithChannelListCallback);
GProGuild getGuildInfoFromCache(long j2); GProGuild getGuildInfoFromCache(long guildId);
// 第一次请求: startIndex = 0 , roleIdIndex = 2 // 第一次请求: startIndex = 0 , roleIdIndex = 2
void fetchMemberListWithRole(long guildId, long channelId, long startIndex, long roleIndex, int count, int seq, IGProFetchMemberListWithRoleCallback cb); void fetchMemberListWithRole(long guildId, long channelId, long startIndex, long roleIndex, int count, int seq, IGProFetchMemberListWithRoleCallback cb);
@ -41,14 +41,23 @@ public interface IKernelGuildService {
void refreshGuildInfoOnly(long j2, boolean z, int i2); void refreshGuildInfoOnly(long j2, boolean z, int i2);
void fetchMemberRoles(long guildId, long channelId, long tinyId, int seq, IGProFetchMemberRolesCallback cb);
void refreshGuildUserProfileInfo(long guildId, long tinyId, int seq); void refreshGuildUserProfileInfo(long guildId, long tinyId, int seq);
void fetchUserInfo(long guildId, long channelId, ArrayList<Long> tinyIdList, int seq, IGProGetUserInfoCallback cb); void fetchUserInfo(long guildId, long channelId, ArrayList<Long> tinyIdList, int seq, IGProGetUserInfoCallback cb);
@Deprecated(since = "QQ新版本不支持创建话题子频道")
void fetchTopFeeds(long guildId, long channelId, IGProFetchTopFeedsCallback cb); void fetchTopFeeds(long guildId, long channelId, IGProFetchTopFeedsCallback cb);
void fetchChannelInvisibleRoleList(long guildId, long channelId, IGProFetchChannelInvisibleRoleListCallback cb);
void fetchChannelLiveableRoleList(long guildId, long channelId, IGProFetchChannelLiveableRoleListCallback cb);
void fetchMemberRoles(long guildId, long channelId, long tinyId, int seq, IGProFetchMemberRolesCallback cb);
void fetchRoleListWithPermission(long guildId, int seq, IGProFetchRoleListPermissionCallback cb);
void fetchRoleWithPermission(long guildId, long roleId, int seq, IGProFetchRolePermissionCallback cb);
GProSimpleProfile getSimpleProfile(long guildId, long tinyId, int seq); GProSimpleProfile getSimpleProfile(long guildId, long tinyId, int seq);
GProFaceAuthInfo getFaceAuthInfo(); GProFaceAuthInfo getFaceAuthInfo();

View File

@ -44,7 +44,7 @@ internal abstract class BaseSvc {
suspend fun sendOidbAW(cmd: String, cmdId: Int, serviceId: Int, data: ByteArray, trpc: Boolean = false, timeout: Long = 5000L): ByteArray? { suspend fun sendOidbAW(cmd: String, cmdId: Int, serviceId: Int, data: ByteArray, trpc: Boolean = false, timeout: Long = 5000L): ByteArray? {
val seq = MsfCore.getNextSeq() val seq = MsfCore.getNextSeq()
return withTimeoutOrNull(timeout) { val buffer = withTimeoutOrNull(timeout) {
suspendCancellableCoroutine { continuation -> suspendCancellableCoroutine { continuation ->
GlobalScope.launch(Dispatchers.Default) { GlobalScope.launch(Dispatchers.Default) {
DynamicReceiver.register(IPCRequest(cmd, seq) { DynamicReceiver.register(IPCRequest(cmd, seq) {
@ -59,6 +59,16 @@ internal abstract class BaseSvc {
if (it == null) if (it == null)
DynamicReceiver.unregister(seq) DynamicReceiver.unregister(seq)
}?.copyOf() }?.copyOf()
try {
if (buffer != null && buffer.size >= 5 && buffer[4] == 120.toByte()) {
val builder = BytePacketBuilder()
val deBuffer = DeflateTools.uncompress(buffer.slice(4))
builder.writeInt(deBuffer.size)
builder.writeFully(deBuffer)
return builder.build().readBytes()
}
} catch (_: Exception) { }
return buffer
} }
suspend fun sendBufferAW(cmd: String, isPb: Boolean, data: ByteArray, timeout: Long = 5000L): ByteArray? { suspend fun sendBufferAW(cmd: String, isPb: Boolean, data: ByteArray, timeout: Long = 5000L): ByteArray? {
@ -141,7 +151,7 @@ internal abstract class BaseSvc {
protected suspend fun sendAW(toServiceMsg: ToServiceMsg, timeout: Long = 5000L): ByteArray? { protected suspend fun sendAW(toServiceMsg: ToServiceMsg, timeout: Long = 5000L): ByteArray? {
val seq = MsfCore.getNextSeq() val seq = MsfCore.getNextSeq()
return withTimeoutOrNull<ByteArray?>(timeout) { val buffer = withTimeoutOrNull<ByteArray?>(timeout) {
suspendCancellableCoroutine { continuation -> suspendCancellableCoroutine { continuation ->
GlobalScope.launch(Dispatchers.Default) { GlobalScope.launch(Dispatchers.Default) {
DynamicReceiver.register(IPCRequest(toServiceMsg.serviceCmd, seq) { DynamicReceiver.register(IPCRequest(toServiceMsg.serviceCmd, seq) {
@ -155,6 +165,16 @@ internal abstract class BaseSvc {
}.also { }.also {
if (it == null) DynamicReceiver.unregister(seq) if (it == null) DynamicReceiver.unregister(seq)
}?.copyOf() }?.copyOf()
try {
if (buffer != null && buffer.size >= 5 && buffer[4] == 120.toByte()) {
val builder = BytePacketBuilder()
val deBuffer = DeflateTools.uncompress(buffer.slice(4))
builder.writeInt(deBuffer.size)
builder.writeFully(deBuffer)
return builder.build().readBytes()
}
} catch (_: Exception) { }
return buffer
} }
protected fun sendExtra(cmd: String, builder: (Bundle) -> Unit) { protected fun sendExtra(cmd: String, builder: (Bundle) -> Unit) {

View File

@ -284,4 +284,16 @@ internal object GProSvc: BaseSvc() {
return result return result
} }
suspend fun getGuildRoles(guildId: ULong): Result<List<GProGuildRole>> {
val kernelGProService = NTServiceFetcher.kernelService.wrapperSession.guildService
val roles: List<GProGuildRole> = withTimeoutOrNull(5000) {
suspendCancellableCoroutine {
kernelGProService.fetchRoleListWithPermission(guildId.toLong(), 1) { code, _, roles, _, _, _ ->
if (code != 0) it.resume(null) else it.resume(roles)
}
}
} ?: return Result.failure(Exception("unable to fetch guild roles"))
return Result.success(roles)
}
} }

View File

@ -0,0 +1,61 @@
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.remote.action.handlers.GetGuildMemberProfile.Permission
import moe.fuqiuluo.shamrock.tools.EmptyJsonString
import moe.fuqiuluo.symbols.OneBotHandler
@OneBotHandler("get_guild_roles")
internal object GetGuildRoles: IActionHandler() {
override suspend fun internalHandle(session: ActionSession): String {
val guildId = session.getString("guild_id").toULong()
return invoke(guildId, session.echo)
}
suspend operator fun invoke(guildId: ULong, echo: JsonElement = EmptyJsonString): String {
val result = GProSvc.getGuildRoles(guildId).onFailure {
return error(it.message ?: "unable to fetch guild roles", echo)
}.getOrThrow()
return ok(GetGuildRolesResult(result.map {
GuildRole(
color = it.color,
disabled = it.count <= 0,
independent = it.isChannelRole,
maxCount = it.memberLimit,
memberCount = it.count,
owned = it.bHoist,
roleId = it.roleId,
roleName = it.name,
permission = it.rolePermissions.permissionList.map {
Permission(it.rootId, it.childIds)
},
)
}), echo = echo)
}
override val requiredParams: Array<String> = arrayOf("guild_id")
@Serializable
data class GetGuildRolesResult(
@SerialName("roles") val roles: List<GuildRole>
)
@Serializable
data class GuildRole(
@SerialName("argb_color") val color: Long,
@SerialName("disabled") val disabled: Boolean,
@SerialName("independent") val independent: Boolean,
@SerialName("max_count") val maxCount: Int,
@SerialName("member_count") val memberCount: Int,
@SerialName("owned") val owned: Boolean,
@SerialName("role_id") val roleId: Long,
@SerialName("role_name") val roleName: String,
@SerialName("permission") val permission: List<Permission>,
)
}

View File

@ -9,10 +9,12 @@ import io.ktor.server.routing.post
import io.ktor.server.routing.route import io.ktor.server.routing.route
import moe.fuqiuluo.shamrock.helper.MessageHelper import moe.fuqiuluo.shamrock.helper.MessageHelper
import moe.fuqiuluo.shamrock.remote.action.handlers.GetGProChannelList import moe.fuqiuluo.shamrock.remote.action.handlers.GetGProChannelList
import moe.fuqiuluo.shamrock.remote.action.handlers.GetGuildFeeds
import moe.fuqiuluo.shamrock.remote.action.handlers.GetGuildList import moe.fuqiuluo.shamrock.remote.action.handlers.GetGuildList
import moe.fuqiuluo.shamrock.remote.action.handlers.GetGuildMemberList import moe.fuqiuluo.shamrock.remote.action.handlers.GetGuildMemberList
import moe.fuqiuluo.shamrock.remote.action.handlers.GetGuildMemberProfile import moe.fuqiuluo.shamrock.remote.action.handlers.GetGuildMemberProfile
import moe.fuqiuluo.shamrock.remote.action.handlers.GetGuildMetaByGuest import moe.fuqiuluo.shamrock.remote.action.handlers.GetGuildMetaByGuest
import moe.fuqiuluo.shamrock.remote.action.handlers.GetGuildRoles
import moe.fuqiuluo.shamrock.remote.action.handlers.GetGuildServiceProfile import moe.fuqiuluo.shamrock.remote.action.handlers.GetGuildServiceProfile
import moe.fuqiuluo.shamrock.remote.action.handlers.SendGuildMessage import moe.fuqiuluo.shamrock.remote.action.handlers.SendGuildMessage
import moe.fuqiuluo.shamrock.remote.action.handlers.SendMessage import moe.fuqiuluo.shamrock.remote.action.handlers.SendMessage
@ -109,4 +111,16 @@ fun Routing.guildAction() {
}, ContentType.Application.Json) }, ContentType.Application.Json)
} }
} }
getOrPost("/get_guild_feeds") {
val guildId = fetchOrThrow("guild_id").toULong()
val channelId = fetchOrNull("channel_id")?.toULong() ?: 0uL
val from = fetchOrNull("from")?.toInt() ?: 0
call.respondText(GetGuildFeeds(guildId, channelId, from), ContentType.Application.Json)
}
getOrPost("/get_guild_roles") {
val guildId = fetchOrThrow("guild_id").toULong()
call.respondText(GetGuildRoles(guildId), ContentType.Application.Json)
}
} }