From b845ad4dc88f070ff22a450d9b91f2e53ef5b5d1 Mon Sep 17 00:00:00 2001 From: 17146 <1714673995@qq.com> Date: Fri, 27 Jun 2025 12:57:53 +0800 Subject: [PATCH] =?UTF-8?q?=E5=B0=9D=E8=AF=95=E6=B7=BB=E5=8A=A0DronesTool?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../superbwarfare/tools/DronesTool.java | 137 ++++++++++++++++++ 1 file changed, 137 insertions(+) create mode 100644 src/main/java/com/atsuishio/superbwarfare/tools/DronesTool.java diff --git a/src/main/java/com/atsuishio/superbwarfare/tools/DronesTool.java b/src/main/java/com/atsuishio/superbwarfare/tools/DronesTool.java new file mode 100644 index 000000000..a97fadd10 --- /dev/null +++ b/src/main/java/com/atsuishio/superbwarfare/tools/DronesTool.java @@ -0,0 +1,137 @@ +package com.atsuishio.superbwarfare.tools; + +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.level.Level; + +import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; + +/** + * Code based on @Mafuyu404's DiligentStalker + */ +public class DronesTool { + + private final UUID playerUUID; + private final int droneId; + public final Level level; + public static final ConcurrentHashMap INSTANCE_MAP = new ConcurrentHashMap<>(); + + private static final ConcurrentHashMap INSTANCE_CACHE = new ConcurrentHashMap<>(); + private static final ConcurrentHashMap DRONES_CACHE = new ConcurrentHashMap<>(); + private static final ConcurrentHashMap DRONE_TO_PLAYER = new ConcurrentHashMap<>(); + + // 缓存失效时间 + private static final long CACHE_EXPIRE_TIME = 5000; + private long lastAccessTime; + + public DronesTool(UUID playerUUID, int droneId, Level level) { + this.playerUUID = playerUUID; + this.droneId = droneId; + this.level = level; + this.lastAccessTime = System.currentTimeMillis(); + } + + public Player getPlayer() { + this.lastAccessTime = System.currentTimeMillis(); + return this.level.getPlayerByUUID(this.playerUUID); + } + + public Entity getDrone() { + this.lastAccessTime = System.currentTimeMillis(); + return this.level.getEntity(this.droneId); + } + + public static DronesTool connect(Player player, Entity stalker) { + if (player == null || stalker == null) return null; + if (hasInstanceOf(player) || hasInstanceOf(stalker)) return null; + + if (player.level().isClientSide) { + // TODO 向客户端发送连接的网络包 + } + + INSTANCE_MAP.put(player.getUUID(), stalker.getId()); + DRONE_TO_PLAYER.put(stalker.getId(), player.getUUID()); + + DronesTool instance = new DronesTool(player.getUUID(), stalker.getId(), player.level()); + INSTANCE_CACHE.put(player.getUUID(), instance); + DRONES_CACHE.put(stalker.getId(), instance); + + return instance; + } + + public static DronesTool getInstanceOf(Entity entity) { + if (entity == null) return null; + + UUID uuid = entity.getUUID(); + int id = entity.getId(); + + DronesTool cache = INSTANCE_CACHE.get(uuid); + if (cache != null && !isCacheExpired(cache)) { + return cache; + } + + cache = DRONES_CACHE.get(id); + if (cache != null && !isCacheExpired(cache)) { + return cache; + } + + boolean isPlayer = INSTANCE_MAP.containsKey(uuid); + boolean isDrone = DRONE_TO_PLAYER.containsKey(id); + + DronesTool instance = null; + if (isPlayer) { + var stalkerId = INSTANCE_MAP.get(uuid); + if (stalkerId != null) { + instance = new DronesTool(uuid, stalkerId, entity.level()); + INSTANCE_CACHE.put(uuid, instance); + } + } else if (isDrone) { + UUID playerUUID = DRONE_TO_PLAYER.get(id); + if (playerUUID != null) { + instance = new DronesTool(playerUUID, id, entity.level()); + DRONES_CACHE.put(id, instance); + } + } + + return instance; + } + + public void disconnect() { + if (level.isClientSide) { + // TODO 向客户端发送断开连接的网络包 + } + INSTANCE_MAP.remove(this.playerUUID); + DRONE_TO_PLAYER.remove(this.droneId); + INSTANCE_CACHE.remove(this.playerUUID); + DRONES_CACHE.remove(this.droneId); + } + + public static boolean hasInstanceOf(Entity entity) { + if (entity == null) return false; + + UUID uuid = entity.getUUID(); + if (INSTANCE_CACHE.containsKey(uuid) && !isCacheExpired(INSTANCE_CACHE.get(uuid))) { + return true; + } + + int id = entity.getId(); + if (DRONES_CACHE.containsKey(id) && !isCacheExpired(DRONES_CACHE.get(id))) { + return true; + } + + return (INSTANCE_MAP.containsKey(uuid) || INSTANCE_MAP.containsValue(id)); + } + + private static boolean isCacheExpired(DronesTool instance) { + return System.currentTimeMillis() - instance.lastAccessTime > CACHE_EXPIRE_TIME; + } + + public static void cleanupExpiredCache() { + long currentTime = System.currentTimeMillis(); + INSTANCE_CACHE.entrySet().removeIf(entry -> + currentTime - entry.getValue().lastAccessTime > CACHE_EXPIRE_TIME); + DRONES_CACHE.entrySet().removeIf(entry -> + currentTime - entry.getValue().lastAccessTime > CACHE_EXPIRE_TIME); + } +}