This commit is contained in:
fuqiuluo 2024-07-17 17:25:16 +08:00
parent 36ed55d220
commit c49861d982
9 changed files with 233 additions and 63 deletions

View File

@ -1,63 +1,92 @@
package com.tencent.mobileqq.data.troop;
import org.jetbrains.annotations.Nullable;
import com.tencent.qqnt.kernelpublic.nativeinterface.MemberRole;
public class TroopMemberInfo {
public long active_point;
public static final long VALUE_DISTANCE_TO_SELF_UNKOWN = -100;
protected static final int VALUE_INVALID = -100;
public static final long VALUE_MEMBER_CLOSE_SHARE_LBS = -1001;
public int addState;
public byte age;
public String alias;
@Deprecated(since = "推荐使用TroopMemberNickInfo")
public String autoremark;
public long cmduinFlagEx3Grocery;
public long credit_level;
public long datetime;
public String displayedNamePinyinFirst;
public short faceid;
@Nullable
public TroopMemberInfoExt extInfo;
@Deprecated(since = "推荐使用TroopMemberNickInfo")
public String friendnick;
public long gagTimeStamp;
public String honorList;
public boolean isTroopFollowed;
public long join_time;
public long last_active_time;
public int level;
public int mBigClubVipType;
public byte mHonorRichFlag;
public boolean mIsShielded;
public int mVipType;
public String memberUid;
public String memberuin;
public int newRealLevel;
public TroopMemberNickInfo nickInfo;
public int realLevel;
public MemberRole role;
@Nullable
public TroopMemberSpecialTitleInfo specialTitleInfo;
@Deprecated(since = "推荐使用TroopMemberNickInfo")
public String troopColorNick;
@Deprecated(since = "推荐使用TroopMemberNickInfo")
public int troopColorNickId;
@Deprecated(since = "推荐使用TroopMemberNickInfo")
public String troopnick;
public String troopuin;
public int globalTroopLevel = VALUE_INVALID;
public int flagEx = 0;
// QQ OLD API DATA
public long active_point;
public byte age;
public String alias;
public long cmduinFlagEx3Grocery;
public long datetime;
public short faceid;
public String hwCourse;
public int hwIdentity;
public String hwName;
public int isShowQZone;
public boolean isTroopFollowed;
public long join_time;
public long lastMsgUpdateHonorRichTime;
public long last_active_time;
public int level;
public int mBigClubTemplateId;
public int mBigClubVipLevel;
public int mBigClubVipType;
public int mGlamourLevel;
public byte mHonorRichFlag;
public int mIsHideBigClub;
public boolean mIsShielded;
public String mUniqueTitle;
public int mVipLevel;
public int mVipTemplateId;
public int mVipType;
public String memberuin;
public int newRealLevel;
public String pyAll_autoremark;
public String pyAll_friendnick;
public String pyAll_troopnick;
public String pyFirst_autoremark;
public String pyFirst_friendnick;
public String pyFirst_troopnick;
public int realLevel;
public String recommendRemark;
public byte sex;
public byte status;
public int tribeLevel;
public int tribePoint;
public String troopColorNick;
public int troopColorNickId;
public String troopnick;
public String troopremark;
public String troopuin;
public int qqVipInfo = 0;
public int superQqInfo = 0;
public int superVipInfo = 0;
public int hotChatGlamourLevel = -100;
public int globalTroopLevel = -100;
public int distance = 0;
public long msgseq = -100;
public double distanceToSelf = -100.0d;

View File

@ -0,0 +1,48 @@
package com.tencent.mobileqq.data.troop;
import org.jetbrains.annotations.Nullable;
import kotlin.jvm.JvmField;
public class TroopMemberInfoExt {
@JvmField
public int commonFrdCnt;
@JvmField
public long flagEx3;
@JvmField
public int hwIdentity;
@JvmField
public long lastMsgUpdateHonorRichTime;
@JvmField
@Nullable
public String memberUin;
@JvmField
@Nullable
public byte[] nickIconRepeatMsgBuffer;
@JvmField
@Nullable
public String recommendRemark;
@JvmField
@Nullable
public String showNameForPinyin;
@JvmField
@Nullable
public String showNamePinyinAll;
@JvmField
@Nullable
public String showNamePinyinFirst;
@JvmField
@Nullable
public String troopUin;
}

View File

@ -0,0 +1,29 @@
package com.tencent.mobileqq.data.troop;
import org.jetbrains.annotations.NotNull;
public class TroopMemberSpecialTitleInfo {
public final int getExpireTimeSec() {
return 0;
}
@NotNull
public final String getFriendNick() {
return null;
}
@NotNull
public final String getSpecialTitle() {
return null;
}
@NotNull
public final String getTroopUin() {
return null;
}
@NotNull
public final String getUin() {
return null;
}
}

View File

@ -56,6 +56,7 @@ import moe.fuqiuluo.qqinterface.servlet.structures.ProhibitedMemberInfo
import moe.fuqiuluo.shamrock.helper.Level
import moe.fuqiuluo.shamrock.helper.LogCenter
import moe.fuqiuluo.shamrock.helper.MessageHelper
import moe.fuqiuluo.shamrock.remote.action.handlers.GetTroopMemberInfo
import moe.fuqiuluo.shamrock.remote.service.data.EssenceMessage
import moe.fuqiuluo.shamrock.remote.service.data.GroupAnnouncement
import moe.fuqiuluo.shamrock.remote.service.data.GroupAnnouncementMessage
@ -476,12 +477,21 @@ internal object GroupSvc: QQInterfaces() {
return groupInfo.troopowneruin == app.account
}
fun isAdmin(groupId: Long): Boolean {
suspend fun isAdmin(groupId: Long): Boolean {
if (PlatformUtils.getQQVersionCode() > QQ_9_0_65_VER) {
// 针对新版本api做的适配
val account = app.longAccountUin
getTroopMemberInfoByUinV2(groupId, account, false).onSuccess {
if (it.role == com.tencent.qqnt.kernelpublic.nativeinterface.MemberRole.ADMIN
|| it.role == com.tencent.qqnt.kernelpublic.nativeinterface.MemberRole.OWNER) {
return true
}
}
}
val service = app
.getRuntimeService(ITroopInfoService::class.java, "all")
val groupInfo = service.getTroopInfo(groupId.toString())
return groupInfo.isAdmin || groupInfo.troopowneruin == app.account
}

View File

@ -17,7 +17,7 @@ internal object BanTroopMember: IActionHandler() {
return invoke(groupId, userId, duration, session.echo)
}
operator fun invoke(
suspend operator fun invoke(
groupId: Long,
userId: Long,
duration: Int = 30 * 60,

View File

@ -1,11 +1,14 @@
package moe.fuqiuluo.shamrock.remote.action.handlers
import com.tencent.mobileqq.data.Card
import com.tencent.mobileqq.data.troop.TroopMemberInfo
import com.tencent.qqnt.kernelpublic.nativeinterface.MemberRole as NtMemberRole
import kotlinx.serialization.json.JsonElement
import moe.fuqiuluo.qqinterface.servlet.GroupSvc
import moe.fuqiuluo.shamrock.remote.action.ActionSession
import moe.fuqiuluo.shamrock.remote.action.IActionHandler
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.ifNullOrEmpty
import moe.fuqiuluo.shamrock.utils.PlatformUtils
@ -32,13 +35,60 @@ internal object GetTroopMemberInfo : IActionHandler() {
return error(it.message ?: "unknown error", echo)
}.getOrThrow()
return ok(
SimpleTroopMemberInfo(
val code = PlatformUtils.getQQVersionCode()
return ok(when {
(code >= QQ_9_0_65_VER) -> ntQQApiData(groupId, userId, info)
else -> oldQQApiData(groupId, userId, info)
}, echo)
}
private suspend fun ntQQApiData(groupId: Long, userId: Long, info: TroopMemberInfo): SimpleTroopMemberInfo {
return SimpleTroopMemberInfo(
uin = info.memberuin.toLong(),
name = info.friendnick.ifNullOrEmpty(info.autoremark) ?: "",
showName = info.troopnick.ifNullOrEmpty(info.troopColorNick),
cardName = info.troopnick.ifNullOrEmpty(info.troopColorNick),
distance = info.distance,
distance = 0,
honor = GroupSvc.parseHonor(info.honorList),
joinTime = info.join_time,
lastActiveTime = info.last_active_time,
uniqueName = null,
groupId = groupId,
nick = info.friendnick.ifNullOrEmpty(info.autoremark) ?: "",
sex = "unknown",
area = "",
lastSentTime = info.last_active_time,
level = info.level,
role = when(info.role) {
NtMemberRole.UNSPECIFIED -> MemberRole.Unknown
NtMemberRole.STRANGER -> MemberRole.Stranger
NtMemberRole.MEMBER -> MemberRole.Member
NtMemberRole.ADMIN -> MemberRole.Admin
NtMemberRole.OWNER -> MemberRole.Owner
null -> MemberRole.Unknown
},
unfriendly = false,
title = "",
titleExpireTime = 0,
cardChangeable = info.role == NtMemberRole.OWNER || info.role == NtMemberRole.ADMIN,
age = 0,
shutUpTimestamp = 0L
).also {
if (info.specialTitleInfo != null) {
it.uniqueName = info.specialTitleInfo?.specialTitle ?: ""
it.title = info.specialTitleInfo?.specialTitle ?: ""
it.titleExpireTime = info.specialTitleInfo?.expireTimeSec ?: 0
}
}
}
private suspend fun oldQQApiData(groupId: Long, userId: Long, info: TroopMemberInfo): SimpleTroopMemberInfo {
return SimpleTroopMemberInfo(
uin = info.memberuin.toLong(),
name = info.friendnick.ifNullOrEmpty(info.autoremark) ?: "",
showName = info.troopnick.ifNullOrEmpty(info.troopColorNick),
cardName = info.troopnick.ifNullOrEmpty(info.troopColorNick),
distance = 0,
honor = GroupSvc.parseHonor(info.honorList),
joinTime = info.join_time,
lastActiveTime = info.last_active_time,
@ -50,7 +100,7 @@ internal object GetTroopMemberInfo : IActionHandler() {
Card.MALE -> "male"
else -> "unknown"
},
area = info.alias ?: "",
area = "",
lastSentTime = info.last_active_time,
level = info.level,
role = GroupSvc.getMemberRole(groupId, userId),
@ -60,8 +110,12 @@ internal object GetTroopMemberInfo : IActionHandler() {
cardChangeable = GroupSvc.isAdmin(groupId),
age = info.age.toInt(),
shutUpTimestamp = 0L
), echo
)
).also {
if (PlatformUtils.getQQVersionCode() <= QQ_9_0_65_VER) {
it.distance = info.distance
it.area = info.alias
}
}
}
override val requiredParams: Array<String> = arrayOf("user_id", "group_id")

View File

@ -17,7 +17,7 @@ internal object ModifyTroopMemberName: IActionHandler() {
return invoke(groupId, userId, name, session.echo)
}
operator fun invoke(groupId: Long, userId: Long, card: String, echo: JsonElement = EmptyJsonString): String {
suspend operator fun invoke(groupId: Long, userId: Long, card: String, echo: JsonElement = EmptyJsonString): String {
if (!GroupSvc.isAdmin(groupId) && userId != TicketSvc.getUin().toLong()) {
return logic("you are not admin", echo)
}

View File

@ -16,7 +16,7 @@ internal object ModifyTroopName: IActionHandler() {
return invoke(groupId, groupName, session.echo)
}
operator fun invoke(groupId: Long, name: String, echo: JsonElement = EmptyJsonString): String {
suspend operator fun invoke(groupId: Long, name: String, echo: JsonElement = EmptyJsonString): String {
return if (GroupSvc.isAdmin(groupId)) {
GroupSvc.modifyTroopName(groupId, name)
ok("成功", echo)

View File

@ -27,18 +27,18 @@ internal data class SimpleTroopMemberInfo(
@SerialName("user_name") val name: String,
@SerialName("sex") val sex: String,
@SerialName("age") val age: Int,
@SerialName("title") val title: String,
@SerialName("title_expire_time") val titleExpireTime: Int,
@SerialName("title") var title: String?,
@SerialName("title_expire_time") var titleExpireTime: Int,
@SerialName("nickname") val nick: String,
@SerialName("user_displayname") val showName: String?,
@SerialName("card") val cardName: String?,
@SerialName("distance") val distance: Int,
@SerialName("distance") var distance: Int,
@SerialName("honor") val honor: List<Int>,
@SerialName("join_time") val joinTime: Long,
@SerialName("last_active_time") val lastActiveTime: Long,
@SerialName("last_sent_time") val lastSentTime: Long,
@SerialName("unique_name") val uniqueName: String?,
@SerialName("area") val area: String,
@SerialName("unique_name") var uniqueName: String?,
@SerialName("area") var area: String,
@SerialName("level") val level: Int,
@SerialName("role") val role: MemberRole,
@SerialName("unfriendly") val unfriendly: Boolean,