From 91ac6e096cc964ed3d20449ec65cb2a2a7c07a91 Mon Sep 17 00:00:00 2001 From: YuKun Liu Date: Fri, 30 Jan 2026 00:08:08 -0800 Subject: [PATCH] feat: code --- .../mineroo/common/cache/UserInfoCache.java | 96 +++++++++++++++++++ .../mineroo/common/request/UserRequest.java | 51 ++++++++++ .../online/mineroo/paper/MinerooCore.java | 19 +++- .../expansions/MinerooUserExpansion.java | 5 +- .../paper/listeners/PlayerBindListener.java | 19 +++- .../mineroo/paper/structure/PlayerInfo.java | 13 --- paper/src/main/resources/paper-plugin.yml | 6 ++ 7 files changed, 188 insertions(+), 21 deletions(-) create mode 100644 common/src/main/java/online/mineroo/common/cache/UserInfoCache.java delete mode 100644 paper/src/main/java/online/mineroo/paper/structure/PlayerInfo.java diff --git a/common/src/main/java/online/mineroo/common/cache/UserInfoCache.java b/common/src/main/java/online/mineroo/common/cache/UserInfoCache.java new file mode 100644 index 0000000..28b6906 --- /dev/null +++ b/common/src/main/java/online/mineroo/common/cache/UserInfoCache.java @@ -0,0 +1,96 @@ +package online.mineroo.common.cache; + +import java.time.LocalDateTime; +import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; +import online.mineroo.common.request.UserRequest.SimpleUserInfoResponse; + +public class UserInfoCache { + private ConcurrentHashMap uuidMap = new ConcurrentHashMap<>(); + private ConcurrentHashMap simpleUserInfo = new ConcurrentHashMap<>(); + + public UserInfoCache() {} + + public UUID insert(UUID uuid, SimpleUserInfoResponse simpleUserInfoResponse) { + this.simpleUserInfo.put(uuid, new SimpleUserCacheInfo(simpleUserInfoResponse)); + return uuid; + } + + public UUID insert(String name, SimpleUserInfoResponse simpleUserInfoResponse) { + if (this.uuidMap.containsKey(name.toLowerCase())) { + UUID uuid = this.uuidMap.get(name.toLowerCase()); + this.simpleUserInfo.put(uuid, new SimpleUserCacheInfo(simpleUserInfoResponse)); + return uuid; + } + return null; + } + + public SimpleUserInfoResponse get(UUID uuid) { + SimpleUserCacheInfo info = this.simpleUserInfo.get(uuid); + + if (info == null) { + return null; + } + + // LocalDateTime expireTime = info.getTime().plusHours(24); + // if (LocalDateTime.now().isAfter(expireTime)) { + // return null; + // } + + return info.getData(); + } + + public SimpleUserInfoResponse get(String name) { + if (name == null) { + return null; + } + + UUID uuid = this.uuidMap.get(name.toLowerCase()); + if (uuid == null) { + return null; + } + return this.get(uuid); + } + + public void remove(UUID uuid) { + if (uuid == null) { + return; + } + this.simpleUserInfo.remove(uuid); + this.uuidMap.values().removeIf(val -> val.equals(uuid)); + } + + public void updateNameMapping(String name, UUID uuid) { + if (name != null && uuid != null) { + this.uuidMap.put(name.toLowerCase(), uuid); + } + } + + public void cleanup() { + // LocalDateTime now = LocalDateTime.now(); + // + // simpleUserInfo.entrySet().removeIf(entry -> { + // return now.isAfter(entry.getValue().getTime().plusHours(24)); + // }); + // + // uuidMap.entrySet().removeIf(entry -> !simpleUserInfo.containsKey(entry.getValue())); + } + + public static class SimpleUserCacheInfo { + private SimpleUserInfoResponse data; + private LocalDateTime time; + + public SimpleUserCacheInfo(SimpleUserInfoResponse data) { + this.data = data; + this.time = LocalDateTime.now(); + } + + public SimpleUserInfoResponse getData() { + return this.data; + } + + public LocalDateTime getTime() { + return this.time; + } + } +} diff --git a/common/src/main/java/online/mineroo/common/request/UserRequest.java b/common/src/main/java/online/mineroo/common/request/UserRequest.java index 2f725a1..884c2a8 100644 --- a/common/src/main/java/online/mineroo/common/request/UserRequest.java +++ b/common/src/main/java/online/mineroo/common/request/UserRequest.java @@ -27,6 +27,30 @@ public class UserRequest { this.networkService = networkService; } + public static class SimpleUserInfoResponse implements Serializable { + @SerializedName("username") private String username; + @SerializedName("nickname") private String nickname; + @SerializedName("avatar") private String avatar; + @SerializedName("user_id") private int userId; + + // -- Getters + public String getUsername() { + return this.username; + } + + public String getNickname() { + return this.nickname; + } + + public String getAvatar() { + return this.avatar; + } + + public int getUserId() { + return this.userId; + } + } + public class PlayerBindStatusResponse implements Serializable { @SerializedName("status") private PlayerBindStatusEnum status; @@ -244,4 +268,31 @@ public class UserRequest { return createPlayerBindErrorResponse("Network Error: " + e.getMessage()); }); } + + public CompletableFuture getUserInfo(UUID uuid) { + String path = "/server/user/info"; + String simpleUuid = uuid.toString().replace("-", ""); + + Map params = new HashMap<>(); + + params.put("uuid", simpleUuid); + + return networkService.getData(path, params) + .thenApply(response -> { + Gson gson = new Gson(); + if (response.getStatusCode() == 200) { + try { + return gson.fromJson(response.getBody(), SimpleUserInfoResponse.class); + } catch (Exception e) { + logger.warn("Failed to parse UserInfo JSON: " + e.getMessage()); + return null; + } + } + return null; + }) + .exceptionally(e -> { + logger.error("Mineroo Bind: Network exception", e); + return null; + }); + } } diff --git a/paper/src/main/java/online/mineroo/paper/MinerooCore.java b/paper/src/main/java/online/mineroo/paper/MinerooCore.java index d96390b..e8ebd60 100644 --- a/paper/src/main/java/online/mineroo/paper/MinerooCore.java +++ b/paper/src/main/java/online/mineroo/paper/MinerooCore.java @@ -1,16 +1,16 @@ package online.mineroo.paper; import io.papermc.paper.plugin.lifecycle.event.types.LifecycleEvents; -import java.util.HashMap; -import java.util.UUID; import online.mineroo.common.HttpNetworkService; import online.mineroo.common.MessageManager; import online.mineroo.common.NetworkServiceInterface; +import online.mineroo.common.cache.UserInfoCache; import online.mineroo.common.request.RequestClient; import online.mineroo.paper.commands.MainCommand; +import online.mineroo.paper.expansions.MinerooUserExpansion; import online.mineroo.paper.listeners.BindListener; import online.mineroo.paper.listeners.PlayerBindListener; -import online.mineroo.paper.structure.PlayerInfo; +import org.bukkit.Bukkit; import org.bukkit.event.Listener; import org.bukkit.plugin.java.JavaPlugin; @@ -20,7 +20,7 @@ public class MinerooCore extends JavaPlugin implements Listener { private RequestClient requestClient; private Config config; - private HashMap playerCache = new HashMap<>(); + private UserInfoCache userInfoCache; private BindListener bindListener; @@ -42,6 +42,13 @@ public class MinerooCore extends JavaPlugin implements Listener { messageManager = new MessageManager(); getServer().getPluginManager().registerEvents(this, this); + + this.userInfoCache = new UserInfoCache(); + + // regsiter Placeholder + if (Bukkit.getPluginManager().isPluginEnabled("PlaceholderAPI")) { + new MinerooUserExpansion(this).register(); + } } @Override @@ -90,4 +97,8 @@ public class MinerooCore extends JavaPlugin implements Listener { public RequestClient getRequestClient() { return requestClient; } + + public UserInfoCache getUserInfoCache() { + return this.userInfoCache; + } } diff --git a/paper/src/main/java/online/mineroo/paper/expansions/MinerooUserExpansion.java b/paper/src/main/java/online/mineroo/paper/expansions/MinerooUserExpansion.java index 431bef8..39fef64 100644 --- a/paper/src/main/java/online/mineroo/paper/expansions/MinerooUserExpansion.java +++ b/paper/src/main/java/online/mineroo/paper/expansions/MinerooUserExpansion.java @@ -2,6 +2,7 @@ package online.mineroo.paper.expansions; import java.util.UUID; import me.clip.placeholderapi.expansion.PlaceholderExpansion; +import online.mineroo.common.request.UserRequest.SimpleUserInfoResponse; import online.mineroo.paper.MinerooCore; import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; @@ -22,7 +23,7 @@ public class MinerooUserExpansion extends PlaceholderExpansion { @Override @NotNull public String getIdentifier() { - return "example"; + return "mineroo"; } @Override @@ -44,6 +45,8 @@ public class MinerooUserExpansion extends PlaceholderExpansion { UUID uuid = player.getUniqueId(); if (params.equals("name")) { + SimpleUserInfoResponse info = plugin.getUserInfoCache().get(uuid); + return info.getNickname(); } return null; diff --git a/paper/src/main/java/online/mineroo/paper/listeners/PlayerBindListener.java b/paper/src/main/java/online/mineroo/paper/listeners/PlayerBindListener.java index 2b09ef0..defac7f 100644 --- a/paper/src/main/java/online/mineroo/paper/listeners/PlayerBindListener.java +++ b/paper/src/main/java/online/mineroo/paper/listeners/PlayerBindListener.java @@ -51,7 +51,7 @@ public class PlayerBindListener implements Listener { this.plugin = plugin; } - @EventHandler + @EventHandler(priority = EventPriority.LOWEST) public void onPlayerJoin(PlayerJoinEvent event) { Config config = this.plugin.getConfigObject(); MessageManager messageManager = this.plugin.getMessageManager(); @@ -94,10 +94,23 @@ public class PlayerBindListener implements Listener { }, 40L); } + private void onBindSuccess(Player player) { + UUID uuid = player.getUniqueId(); + + restrictedPlayers.remove(uuid); + + plugin.getRequestClient().user().getUserInfo(uuid).thenAccept(response -> { + if (response != null) { + plugin.getUserInfoCache().insert(uuid, response); + plugin.getUserInfoCache().updateNameMapping(player.getName(), uuid); + } + }); + } + private void handleBindStatus(Player player, PlayerBindStatusEnum status, String message) { if (status == PlayerBindStatusEnum.BOUND) { // Player is bound, release restriction - restrictedPlayers.remove(player.getUniqueId()); + onBindSuccess(player); return; } else if (status == PlayerBindStatusEnum.NOT_BOUND) { Dialog dialog = RegistryAccess.registryAccess() @@ -127,7 +140,7 @@ public class PlayerBindListener implements Listener { } if (bindResponse.getStatus() == PlayerBindEnum.BOUND) { - restrictedPlayers.remove(uniqueId); + onBindSuccess(player); player.sendMessage(this.plugin.getMessageManager().get("info.bind.player.success")); } else if (bindResponse.getStatus() == PlayerBindEnum.PENDING) { player.closeDialog(); diff --git a/paper/src/main/java/online/mineroo/paper/structure/PlayerInfo.java b/paper/src/main/java/online/mineroo/paper/structure/PlayerInfo.java deleted file mode 100644 index f479c76..0000000 --- a/paper/src/main/java/online/mineroo/paper/structure/PlayerInfo.java +++ /dev/null @@ -1,13 +0,0 @@ -package online.mineroo.paper.structure; - -public class PlayerInfo { - private String minerooUsername; - - public PlayerInfo(String minerooUsername) { - this.minerooUsername = minerooUsername; - } - - public String getMinerooUsername() { - return this.minerooUsername; - } -} diff --git a/paper/src/main/resources/paper-plugin.yml b/paper/src/main/resources/paper-plugin.yml index 9563bbe..d4d81a3 100644 --- a/paper/src/main/resources/paper-plugin.yml +++ b/paper/src/main/resources/paper-plugin.yml @@ -4,3 +4,9 @@ main: "online.mineroo.paper.MinerooCore" description: Paper Test Plugin api-version: "1.21.10" bootstrapper: "online.mineroo.paper.MinerooCoreBootstrap" + +dependencies: + server: + PlaceholderAPI: + load: BEFORE + required: false