mirror of
https://github.com/whitechi73/OpenShamrock.git
synced 2024-08-14 05:12:17 +00:00
Compare commits
3 Commits
27b4c26da7
...
cf943fd13a
Author | SHA1 | Date | |
---|---|---|---|
cf943fd13a | |||
9608b46799 | |||
502956e3ec |
@ -59,6 +59,7 @@ import moe.fuqiuluo.shamrock.remote.service.data.EssenceMessage
|
|||||||
import moe.fuqiuluo.shamrock.remote.service.data.GroupAnnouncement
|
import moe.fuqiuluo.shamrock.remote.service.data.GroupAnnouncement
|
||||||
import moe.fuqiuluo.shamrock.remote.service.data.GroupAnnouncementMessage
|
import moe.fuqiuluo.shamrock.remote.service.data.GroupAnnouncementMessage
|
||||||
import moe.fuqiuluo.shamrock.remote.service.data.GroupAnnouncementMessageImage
|
import moe.fuqiuluo.shamrock.remote.service.data.GroupAnnouncementMessageImage
|
||||||
|
import moe.fuqiuluo.shamrock.remote.service.data.push.MemberRole
|
||||||
import moe.fuqiuluo.shamrock.tools.EmptyJsonArray
|
import moe.fuqiuluo.shamrock.tools.EmptyJsonArray
|
||||||
import moe.fuqiuluo.shamrock.tools.GlobalClient
|
import moe.fuqiuluo.shamrock.tools.GlobalClient
|
||||||
import moe.fuqiuluo.shamrock.tools.asInt
|
import moe.fuqiuluo.shamrock.tools.asInt
|
||||||
@ -394,6 +395,20 @@ internal object GroupSvc: BaseSvc() {
|
|||||||
.filter { it != 0L }
|
.filter { it != 0L }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
suspend fun getMemberRole(groupId: Long, memberUin: Long): MemberRole {
|
||||||
|
return when(getTroopMemberInfoByUinViaNt(groupId.toString(), memberUin, 3000).getOrNull()?.role) {
|
||||||
|
com.tencent.qqnt.kernel.nativeinterface.MemberRole.STRANGER -> MemberRole.Stranger
|
||||||
|
com.tencent.qqnt.kernel.nativeinterface.MemberRole.MEMBER -> MemberRole.Member
|
||||||
|
com.tencent.qqnt.kernel.nativeinterface.MemberRole.ADMIN -> MemberRole.Admin
|
||||||
|
com.tencent.qqnt.kernel.nativeinterface.MemberRole.OWNER -> MemberRole.Owner
|
||||||
|
com.tencent.qqnt.kernel.nativeinterface.MemberRole.UNSPECIFIED, null -> when (memberUin) {
|
||||||
|
getOwner(groupId.toString()) -> MemberRole.Owner
|
||||||
|
in getAdminList(groupId.toString()) -> MemberRole.Admin
|
||||||
|
else -> MemberRole.Member
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun getOwner(groupId: String): Long {
|
fun getOwner(groupId: String): Long {
|
||||||
val groupInfo = getGroupInfo(groupId)
|
val groupInfo = getGroupInfo(groupId)
|
||||||
return groupInfo.troopowneruin?.toLong() ?: 0
|
return groupInfo.troopowneruin?.toLong() ?: 0
|
||||||
@ -566,23 +581,84 @@ internal object GroupSvc: BaseSvc() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun getTroopMemberInfoByUinViaNt(groupId: String, qq: Long): Result<MemberInfo> {
|
suspend fun getTroopMemberInfoByUinV2(
|
||||||
|
groupId: String,
|
||||||
|
uin: String,
|
||||||
|
refresh: Boolean = false
|
||||||
|
): Result<TroopMemberInfo> {
|
||||||
|
val service = app.getRuntimeService(ITroopMemberInfoService::class.java, "all")
|
||||||
|
var info = service.getTroopMember(groupId, uin)
|
||||||
|
if (refresh || !service.isMemberInCache(groupId, uin) || info == null || info.troopnick == null) {
|
||||||
|
info = requestTroopMemberInfo(service, groupId.toLong(), uin.toLong(), timeout = 2000).getOrNull()
|
||||||
|
}
|
||||||
|
if (info == null) {
|
||||||
|
info = getTroopMemberInfoByUinViaNt(groupId, uin.toLong(), timeout = 2000L).getOrNull()?.let {
|
||||||
|
TroopMemberInfo().apply {
|
||||||
|
troopnick = it.cardName
|
||||||
|
friendnick = it.nick
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
if (info != null && (info.alias == null || info.alias.isBlank())) {
|
||||||
|
val req = group_member_info.ReqBody()
|
||||||
|
req.uint64_group_code.set(groupId.toLong())
|
||||||
|
req.uint64_uin.set(uin.toLong())
|
||||||
|
req.bool_new_client.set(true)
|
||||||
|
req.uint32_client_type.set(1)
|
||||||
|
req.uint32_rich_card_name_ver.set(1)
|
||||||
|
val respBuffer = sendBufferAW("group_member_card.get_group_member_card_info", true, req.toByteArray(), timeout = 2000)
|
||||||
|
if (respBuffer != null) {
|
||||||
|
val rsp = group_member_info.RspBody()
|
||||||
|
rsp.mergeFrom(respBuffer.slice(4))
|
||||||
|
if (rsp.msg_meminfo.str_location.has()) {
|
||||||
|
info.alias = rsp.msg_meminfo.str_location.get().toStringUtf8()
|
||||||
|
}
|
||||||
|
if (rsp.msg_meminfo.uint32_age.has()) {
|
||||||
|
info.age = rsp.msg_meminfo.uint32_age.get().toByte()
|
||||||
|
}
|
||||||
|
if (rsp.msg_meminfo.bytes_group_honor.has()) {
|
||||||
|
val honorBytes = rsp.msg_meminfo.bytes_group_honor.get().toByteArray()
|
||||||
|
val honor = troop_honor.GroupUserCardHonor()
|
||||||
|
honor.mergeFrom(honorBytes)
|
||||||
|
info.level = honor.level.get()
|
||||||
|
// 10315: medal_id not real group level
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (err: Throwable) {
|
||||||
|
LogCenter.log(err.stackTraceToString(), Level.WARN)
|
||||||
|
}
|
||||||
|
return if (info != null) {
|
||||||
|
Result.success(info)
|
||||||
|
} else {
|
||||||
|
Result.failure(Exception("获取群成员信息失败"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun getTroopMemberInfoByUinViaNt(
|
||||||
|
groupId: String,
|
||||||
|
qq: Long,
|
||||||
|
timeout: Long = 5000L
|
||||||
|
): Result<MemberInfo> {
|
||||||
val kernelService = NTServiceFetcher.kernelService
|
val kernelService = NTServiceFetcher.kernelService
|
||||||
val sessionService = kernelService.wrapperSession
|
val sessionService = kernelService.wrapperSession
|
||||||
val groupService = sessionService.groupService
|
val groupService = sessionService.groupService
|
||||||
val info = suspendCancellableCoroutine {
|
val info = withTimeoutOrNull(timeout) {
|
||||||
groupService.getTransferableMemberInfo(groupId.toLong()) { code, _, data ->
|
suspendCancellableCoroutine {
|
||||||
if (code != 0) {
|
groupService.getTransferableMemberInfo(groupId.toLong()) { code, _, data ->
|
||||||
it.resume(null)
|
if (code != 0) {
|
||||||
return@getTransferableMemberInfo
|
it.resume(null)
|
||||||
}
|
return@getTransferableMemberInfo
|
||||||
data.forEach { (_, info) ->
|
|
||||||
if (info.uin == qq) {
|
|
||||||
it.resume(info)
|
|
||||||
return@forEach
|
|
||||||
}
|
}
|
||||||
|
data.forEach { (_, info) ->
|
||||||
|
if (info.uin == qq) {
|
||||||
|
it.resume(info)
|
||||||
|
return@forEach
|
||||||
|
}
|
||||||
|
}
|
||||||
|
it.resume(null)
|
||||||
}
|
}
|
||||||
it.resume(null)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return if (info != null) {
|
return if (info != null) {
|
||||||
@ -748,7 +824,7 @@ internal object GroupSvc: BaseSvc() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun requestTroopMemberInfo(service: ITroopMemberInfoService, groupId: Long, memberUin: Long): Result<TroopMemberInfo> {
|
private suspend fun requestTroopMemberInfo(service: ITroopMemberInfoService, groupId: Long, memberUin: Long, timeout: Long = 10_000): Result<TroopMemberInfo> {
|
||||||
val info = RefreshTroopMemberInfoLock.withLock {
|
val info = RefreshTroopMemberInfoLock.withLock {
|
||||||
val groupIdStr = groupId.toString()
|
val groupIdStr = groupId.toString()
|
||||||
val memberUinStr = memberUin.toString()
|
val memberUinStr = memberUin.toString()
|
||||||
@ -758,7 +834,7 @@ internal object GroupSvc: BaseSvc() {
|
|||||||
requestMemberInfoV2(groupId, memberUin)
|
requestMemberInfoV2(groupId, memberUin)
|
||||||
requestMemberInfo(groupId, memberUin)
|
requestMemberInfo(groupId, memberUin)
|
||||||
|
|
||||||
withTimeoutOrNull(10000) {
|
withTimeoutOrNull(timeout) {
|
||||||
while (!service.isMemberInCache(groupIdStr, memberUinStr)) {
|
while (!service.isMemberInCache(groupIdStr, memberUinStr)) {
|
||||||
delay(200)
|
delay(200)
|
||||||
}
|
}
|
||||||
|
@ -670,17 +670,22 @@ internal object MessageMaker {
|
|||||||
at.atNtUid = "0"
|
at.atNtUid = "0"
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
val info = GroupSvc.getTroopMemberInfoByUin(peerId, qq, true).onFailure {
|
val name = data["name"].asStringOrNull
|
||||||
LogCenter.log("无法获取群成员信息: $qq", Level.ERROR)
|
if (name == null) {
|
||||||
}.getOrNull()
|
val info = GroupSvc.getTroopMemberInfoByUinV2(peerId, qq, true).onFailure {
|
||||||
if (info != null) {
|
LogCenter.log("无法获取群成员信息: $qq", Level.ERROR)
|
||||||
at.content = "@${
|
}.getOrNull()
|
||||||
info.troopnick
|
if (info != null) {
|
||||||
.ifNullOrEmpty(info.friendnick)
|
at.content = "@${
|
||||||
.ifNullOrEmpty(qq)
|
info.troopnick
|
||||||
}"
|
.ifNullOrEmpty(info.friendnick)
|
||||||
|
.ifNullOrEmpty(qq)
|
||||||
|
}"
|
||||||
|
} else {
|
||||||
|
at.content = "@$qq"
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
at.content = "@${data["name"].asStringOrNull.ifNullOrEmpty(qq)}"
|
at.content = "@$name"
|
||||||
}
|
}
|
||||||
at.atType = MsgConstant.ATTYPEONE
|
at.atType = MsgConstant.ATTYPEONE
|
||||||
at.atNtUid = ContactHelper.getUidByUinAsync(qq.toLong())
|
at.atNtUid = ContactHelper.getUidByUinAsync(qq.toLong())
|
||||||
|
@ -52,11 +52,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 = when {
|
role = GroupSvc.getMemberRole(groupId.toLong(), uin.toLong()),
|
||||||
GroupSvc.getOwner(groupId).toString() == uin -> MemberRole.Owner
|
|
||||||
uin.toLong() in GroupSvc.getAdminList(groupId) -> MemberRole.Admin
|
|
||||||
else -> MemberRole.Member
|
|
||||||
},
|
|
||||||
unfriendly = false,
|
unfriendly = false,
|
||||||
title = info.mUniqueTitle ?: "",
|
title = info.mUniqueTitle ?: "",
|
||||||
titleExpireTime = info.mUniqueTitleExpire,
|
titleExpireTime = info.mUniqueTitleExpire,
|
||||||
|
@ -54,12 +54,13 @@ 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 = when {
|
role = GroupSvc.getMemberRole(groupId.toLong(), info.memberuin.toLong())
|
||||||
|
/*when {
|
||||||
GroupSvc.getOwner(groupId)
|
GroupSvc.getOwner(groupId)
|
||||||
.toString() == info.memberuin -> MemberRole.Owner
|
.toString() == info.memberuin -> MemberRole.Owner
|
||||||
info.memberuin.toLong() in GroupSvc.getAdminList(groupId) -> MemberRole.Admin
|
info.memberuin.toLong() in GroupSvc.getAdminList(groupId) -> MemberRole.Admin
|
||||||
else -> MemberRole.Member
|
else -> MemberRole.Member
|
||||||
},
|
}*/,
|
||||||
unfriendly = false,
|
unfriendly = false,
|
||||||
title = info.mUniqueTitle ?: "",
|
title = info.mUniqueTitle ?: "",
|
||||||
titleExpireTime = info.mUniqueTitleExpire,
|
titleExpireTime = info.mUniqueTitleExpire,
|
||||||
|
@ -92,11 +92,11 @@ internal object GlobalEventTransmitter: BaseSvc() {
|
|||||||
.ifEmpty { record.sendMemberName }
|
.ifEmpty { record.sendMemberName }
|
||||||
.ifEmpty { record.peerName },
|
.ifEmpty { record.peerName },
|
||||||
card = record.sendMemberName,
|
card = record.sendMemberName,
|
||||||
role = when (record.senderUin) {
|
role = GroupSvc.getMemberRole(record.peerUin, record.senderUin)/*when (record.senderUin) {
|
||||||
GroupSvc.getOwner(record.peerUin.toString()) -> MemberRole.Owner
|
GroupSvc.getOwner(record.peerUin.toString()) -> MemberRole.Owner
|
||||||
in GroupSvc.getAdminList(record.peerUin.toString()) -> MemberRole.Admin
|
in GroupSvc.getAdminList(record.peerUin.toString()) -> MemberRole.Admin
|
||||||
else -> MemberRole.Member
|
else -> MemberRole.Member
|
||||||
},
|
}*/,
|
||||||
title = "",
|
title = "",
|
||||||
level = "",
|
level = "",
|
||||||
)
|
)
|
||||||
@ -194,7 +194,7 @@ internal object GlobalEventTransmitter: BaseSvc() {
|
|||||||
userId = record.senderUid.toLong(),
|
userId = record.senderUid.toLong(),
|
||||||
nickname = nickName,
|
nickname = nickName,
|
||||||
card = record.sendMemberName,
|
card = record.sendMemberName,
|
||||||
role = MemberRole.Member,
|
role = MemberRole.Member, // TODO(GUILD ROLE)
|
||||||
title = record.sendNickName,
|
title = record.sendNickName,
|
||||||
level = record.roleId.toString(),
|
level = record.roleId.toString(),
|
||||||
tinyId = record.senderUid
|
tinyId = record.senderUid
|
||||||
|
@ -88,7 +88,9 @@ internal data class Anonymous(
|
|||||||
internal enum class MemberRole {
|
internal enum class MemberRole {
|
||||||
@SerialName("owner") Owner,
|
@SerialName("owner") Owner,
|
||||||
@SerialName("admin") Admin,
|
@SerialName("admin") Admin,
|
||||||
@SerialName("member") Member
|
@SerialName("member") Member,
|
||||||
|
@SerialName("stranger") Stranger,
|
||||||
|
@SerialName("unknown") Unknown
|
||||||
}
|
}
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
|
Reference in New Issue
Block a user