Skip to content
This repository has been archived by the owner on Aug 12, 2024. It is now read-only.

Commit

Permalink
Shamrock: support /get_guild_roles
Browse files Browse the repository at this point in the history
  • Loading branch information
whitechi73 committed Feb 2, 2024
1 parent 2f61f6d commit 7952453
Show file tree
Hide file tree
Showing 9 changed files with 149 additions and 5 deletions.
Original file line number Diff line number Diff line change
@@ -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);
}
Original file line number Diff line number Diff line change
@@ -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);
}
Original file line number Diff line number Diff line change
@@ -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);
}
Original file line number Diff line number Diff line change
@@ -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);
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public interface IKernelGuildService {
//void fetchGuestGuildInfoWithChannelList(String guildId, String str2, int i2, int seq, String str3,
// IGProFetchGuestGuildInfoWithChannelListCallback iGProFetchGuestGuildInfoWithChannelListCallback);

GProGuild getGuildInfoFromCache(long j2);
GProGuild getGuildInfoFromCache(long guildId);

// 第一次请求: startIndex = 0 , roleIdIndex = 2
void fetchMemberListWithRole(long guildId, long channelId, long startIndex, long roleIndex, int count, int seq, IGProFetchMemberListWithRoleCallback cb);
Expand All @@ -41,14 +41,23 @@ public interface IKernelGuildService {

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 fetchUserInfo(long guildId, long channelId, ArrayList<Long> tinyIdList, int seq, IGProGetUserInfoCallback cb);

@Deprecated(since = "QQ新版本不支持创建话题子频道")
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);

GProFaceAuthInfo getFaceAuthInfo();
Expand Down
24 changes: 22 additions & 2 deletions xposed/src/main/java/moe/fuqiuluo/qqinterface/servlet/BaseSvc.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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? {
val seq = MsfCore.getNextSeq()
return withTimeoutOrNull(timeout) {
val buffer = withTimeoutOrNull(timeout) {
suspendCancellableCoroutine { continuation ->
GlobalScope.launch(Dispatchers.Default) {
DynamicReceiver.register(IPCRequest(cmd, seq) {
Expand All @@ -59,6 +59,16 @@ internal abstract class BaseSvc {
if (it == null)
DynamicReceiver.unregister(seq)
}?.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? {
Expand Down Expand Up @@ -141,7 +151,7 @@ internal abstract class BaseSvc {

protected suspend fun sendAW(toServiceMsg: ToServiceMsg, timeout: Long = 5000L): ByteArray? {
val seq = MsfCore.getNextSeq()
return withTimeoutOrNull<ByteArray?>(timeout) {
val buffer = withTimeoutOrNull<ByteArray?>(timeout) {
suspendCancellableCoroutine { continuation ->
GlobalScope.launch(Dispatchers.Default) {
DynamicReceiver.register(IPCRequest(toServiceMsg.serviceCmd, seq) {
Expand All @@ -155,6 +165,16 @@ internal abstract class BaseSvc {
}.also {
if (it == null) DynamicReceiver.unregister(seq)
}?.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) {
Expand Down
12 changes: 12 additions & 0 deletions xposed/src/main/java/moe/fuqiuluo/qqinterface/servlet/GProSvc.kt
Original file line number Diff line number Diff line change
Expand Up @@ -284,4 +284,16 @@ internal object GProSvc: BaseSvc() {

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)
}
}
Original file line number Diff line number Diff line change
@@ -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>,
)

}
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,12 @@ import io.ktor.server.routing.post
import io.ktor.server.routing.route
import moe.fuqiuluo.shamrock.helper.MessageHelper
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.GetGuildMemberList
import moe.fuqiuluo.shamrock.remote.action.handlers.GetGuildMemberProfile
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.SendGuildMessage
import moe.fuqiuluo.shamrock.remote.action.handlers.SendMessage
Expand Down Expand Up @@ -109,4 +111,16 @@ fun Routing.guildAction() {
}, 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)
}
}

0 comments on commit 7952453

Please sign in to comment.