如何从URL对应的JSON文件中获取多个UUID用于Minecraft客户端披风判定
Minecraft客户端饰品UUID动态拉取实现方案
核心优化说明
你原有代码存在逻辑缺陷:hasCape方法每次被调用都会往players列表重复插入UUID,会导致列表体积持续膨胀、判断效率越来越低,本次实现同时修复了该问题。
本次实现无需额外引入依赖,直接复用Minecraft自带的Gson库完成JSON解析,采用异步拉取逻辑避免阻塞游戏主线程,同时增加降级逻辑保证网络异常时功能可用。
实现代码
import com.google.gson.Gson; import com.google.gson.annotations.SerializedName; import java.io.BufferedReader; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; import java.util.ArrayList; import java.util.List; import java.util.UUID; import net.minecraft.client.player.AbstractClientPlayer; public class CosmeticsManager { private static final List<UUID> capePlayers = new ArrayList<>(); private static final String COSMETICS_JSON_URL = "https://raw.githubusercontent.com/shovelmods/shovelmods.github.io/main/cosmetics.json"; private static final Gson GSON_INSTANCE = new Gson(); // 类加载时启动异步线程拉取UUID列表,不阻塞游戏启动 static { new Thread(() -> { try { loadRemoteUuidList(); } catch (Exception e) { // 拉取失败时加载默认硬编码UUID作为降级 loadDefaultUuidList(); e.printStackTrace(); } }, "Cosmetics-UUID-Fetcher").start(); } // 从线上拉取并解析UUID列表 private static void loadRemoteUuidList() throws Exception { URL url = new URL(COSMETICS_JSON_URL); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("GET"); connection.setConnectTimeout(5000); connection.setReadTimeout(5000); // 设置UA避免GitHub raw接口拦截请求 connection.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"); BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream())); CosmeticEntry[] entries = GSON_INSTANCE.fromJson(reader, CosmeticEntry[].class); reader.close(); connection.disconnect(); synchronized (capePlayers) { capePlayers.clear(); for (CosmeticEntry entry : entries) { try { capePlayers.add(UUID.fromString(entry.uuid)); } catch (IllegalArgumentException ignored) { // 自动忽略格式错误的UUID } } } } // 降级逻辑:加载原有硬编码的UUID private static void loadDefaultUuidList() { synchronized (capePlayers) { capePlayers.clear(); capePlayers.add(UUID.fromString("288f696b-44d2-4915-a8cc-aa3fd5ea889c")); capePlayers.add(UUID.fromString("ecad61c5-6a42-4018-b1c7-6c5c19ec1cd1")); capePlayers.add(UUID.fromString("093f3473-587b-4a2a-b50f-f4a136e9033b")); capePlayers.add(UUID.fromString("a22ab0ef-18b2-4cc6-ac17-2d9ae40a42ee")); } } public static boolean hasCape(AbstractClientPlayer player) { if (player == null) return false; synchronized (capePlayers) { return capePlayers.contains(player.getUniqueID()); } } // 线上JSON结构对应的映射类,无需解析的字段不用定义 private static class CosmeticEntry { @SerializedName("uuid") String uuid; } }
功能说明
- 后续新增饰品权限仅需要修改GitHub上的JSON文件,不需要重新打包发布客户端,用户重启游戏后会自动拉取最新的UUID列表
- 加了线程锁保证多线程读写安全,不会出现并发异常
- 网络异常时自动降级使用本地硬编码的UUID列表,不会导致饰品功能完全失效
- 判断逻辑复用List的contains方法,比手动遍历更简洁高效
内容的提问来源于stack exchange,提问作者jamig
相关产品推荐
相关产品推荐

