diff --git a/onebot/src/main/java/cn/evole/onebot/sdk/enums/ActionPathEnum.java b/onebot/src/main/java/cn/evole/onebot/sdk/enums/ActionPathEnum.java index 52155457..7bbb73e3 100644 --- a/onebot/src/main/java/cn/evole/onebot/sdk/enums/ActionPathEnum.java +++ b/onebot/src/main/java/cn/evole/onebot/sdk/enums/ActionPathEnum.java @@ -279,6 +279,10 @@ public enum ActionPathEnum implements ActionPath { * 获取 Cookie 和 CSRF Token */ GET_CREDENTIALS("get_credentials"), + /** + * 获取用户资料卡 + */ + GET_USER_INFO("get_user_info"), ; diff --git a/onebot/src/main/java/cn/evole/onebot/sdk/response/misc/UserInfoResp.java b/onebot/src/main/java/cn/evole/onebot/sdk/response/misc/UserInfoResp.java new file mode 100644 index 00000000..4a53b6d0 --- /dev/null +++ b/onebot/src/main/java/cn/evole/onebot/sdk/response/misc/UserInfoResp.java @@ -0,0 +1,83 @@ +package cn.evole.onebot.sdk.response.misc; + +import com.google.gson.annotations.SerializedName; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +/** + * Created on 2022/12/6. + * + * @author MrXiaoM + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class UserInfoResp { + + @SerializedName("user_id") + long uin; + @SerializedName("user_name") + String name; + @SerializedName("user_displayname") + String displayName; + @SerializedName("user_remark") + String remark; + @SerializedName("mail") + String mail; + @SerializedName("find_method") + String findMethod; + @SerializedName("max_vote_cnt") + short maxVoteCnt; + @SerializedName("have_vote_cnt") + short haveVoteCnt; + @SerializedName("vip_list") + List vipList; + @SerializedName("hobby_entry") + String hobbyEntry; + @SerializedName("level") + int level; + @SerializedName("birthday") + long birthday; + @SerializedName("login_day") + long loginDay; + @SerializedName("vote_cnt") + long voteCnt; + @SerializedName("qid") + String qid; + @SerializedName("is_school_verified") + Boolean schoolVerified; + @SerializedName("location") + Location location; + @SerializedName("cookie") + byte[] cookie; + @Data + public static class VipInfo { + /** + * QQ_VIP, + * SUPER_QQ, + * SUPER_VIP, + * QQ_VIDEO, + * QQ_READING, + * BIG_VIP, + * YELLOW_VIP + */ + String type; + int level; + @SerializedName("vip_type") + int vipType; + @SerializedName("template_id") + long templateId; + } + @Data + public static class Location { + String city; + String company; + String country; + String province; + String hometown; + String school; + } +} diff --git a/onebot/src/main/kotlin/cn/evolvefield/onebot/client/core/Bot.kt b/onebot/src/main/kotlin/cn/evolvefield/onebot/client/core/Bot.kt index 186baa7e..9f74bd6c 100644 --- a/onebot/src/main/kotlin/cn/evolvefield/onebot/client/core/Bot.kt +++ b/onebot/src/main/kotlin/cn/evolvefield/onebot/client/core/Bot.kt @@ -1406,6 +1406,24 @@ class Bot( object : TypeToken>() {}.type ) } + + /** + * 获取用户资料卡 + * + * @return [ActionData] of [UserInfoResp] + */ + @JvmBlockingBridge + suspend fun getUserInfo(userId: Long, noCache: Boolean): ActionData { + val action = ActionPathEnum.GET_USER_INFO + val params = JsonObject() + params.addProperty("user_id", userId) + params.addProperty("refresh", noCache) + val result = actionHandler.action(channel, action, params) + return GsonUtil.fromJson( + result.toString(), + object : TypeToken>() {}.type + ) + } } fun List.toJsonArray(): JsonArray { diff --git a/overflow-core/src/main/kotlin/top/mrxiaom/overflow/internal/Overflow.kt b/overflow-core/src/main/kotlin/top/mrxiaom/overflow/internal/Overflow.kt index 704d66f6..a83060e7 100644 --- a/overflow-core/src/main/kotlin/top/mrxiaom/overflow/internal/Overflow.kt +++ b/overflow-core/src/main/kotlin/top/mrxiaom/overflow/internal/Overflow.kt @@ -32,6 +32,7 @@ import top.mrxiaom.overflow.internal.contact.BotWrapper import top.mrxiaom.overflow.internal.contact.BotWrapper.Companion.wrap import top.mrxiaom.overflow.internal.contact.FriendWrapper import top.mrxiaom.overflow.internal.contact.StrangerWrapper +import top.mrxiaom.overflow.internal.data.UserProfileImpl import top.mrxiaom.overflow.internal.data.asMirai import top.mrxiaom.overflow.internal.listener.* import top.mrxiaom.overflow.internal.message.OnebotMessages @@ -205,7 +206,11 @@ class Overflow : IMirai, CoroutineScope, LowLevelApiAccessor, OverflowAPI { @JvmBlockingBridge override suspend fun deserializeMessage(bot: Bot, message: String): MessageChain = OnebotMessages.deserializeFromOneBot(bot, message, null) override suspend fun queryProfile(bot: Bot, targetId: Long): UserProfile { - TODO("Not yet implemented") + val data = bot.asOnebot.impl.getUserInfo(targetId, false).data + // TODO: 不确定 birthday 的单位是毫秒还是秒 + val age = if (data.birthday > 0) ((currentTimeSeconds() - data.birthday) / 365.daysToSeconds).toInt() else 0 + // TODO: 获取性别 + return UserProfileImpl(age, data.mail, 0, data.name, data.level, UserProfile.Sex.UNKNOWN, data.hobbyEntry) } override suspend fun getOnlineOtherClientsList(bot: Bot, mayIncludeSelf: Boolean): List { TODO("Not yet implemented") diff --git a/overflow-core/src/main/kotlin/top/mrxiaom/overflow/internal/data/UserProfileImpl.kt b/overflow-core/src/main/kotlin/top/mrxiaom/overflow/internal/data/UserProfileImpl.kt new file mode 100644 index 00000000..d6b7c9f9 --- /dev/null +++ b/overflow-core/src/main/kotlin/top/mrxiaom/overflow/internal/data/UserProfileImpl.kt @@ -0,0 +1,13 @@ +package top.mrxiaom.overflow.internal.data + +import net.mamoe.mirai.data.UserProfile + +class UserProfileImpl( + override val age: Int, + override val email: String, + override val friendGroupId: Int, + override val nickname: String, + override val qLevel: Int, + override val sex: UserProfile.Sex, + override val sign: String +) : UserProfile