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);
+ }
+}