From 582dd0a4512e595897ce53d9c116ebdfbce10f1c Mon Sep 17 00:00:00 2001 From: Esmorall Date: Fri, 6 Sep 2019 18:35:08 -0300 Subject: [PATCH] Added command /etf check, and change entity id with uuid for persistence --- EntityTrackerFixer/plugin.yml | 6 +- .../entitytrackerfixer/CheckTask.java | 17 ++--- .../EntityTrackerFixer.java | 2 + .../entitytrackerfixer/TrackedWorld.java | 34 +++++---- .../UntrackedEntitiesCache.java | 34 +++++---- .../entitytrackerfixer/UntrackedEntity.java | 12 +++- .../entitytrackerfixer/UntrackerTask.java | 4 +- .../commands/CommandETF.java | 69 +++++++++++++++++++ .../listener/ChunkEventListener.java | 4 +- .../entitytrackerfixer/util/ChatUtils.java | 44 ++++++++++++ 10 files changed, 185 insertions(+), 41 deletions(-) create mode 100644 EntityTrackerFixer/src/net/minemora/entitytrackerfixer/commands/CommandETF.java create mode 100644 EntityTrackerFixer/src/net/minemora/entitytrackerfixer/util/ChatUtils.java diff --git a/EntityTrackerFixer/plugin.yml b/EntityTrackerFixer/plugin.yml index bcbeca3..602aaca 100644 --- a/EntityTrackerFixer/plugin.yml +++ b/EntityTrackerFixer/plugin.yml @@ -1,6 +1,8 @@ name: EntityTrackerFixer main: net.minemora.entitytrackerfixer.EntityTrackerFixer -version: 1.0.9 +version: 1.1 api-version: 1.14 author: Esmorall -commands: \ No newline at end of file +commands: + etf: + usage: / \ No newline at end of file diff --git a/EntityTrackerFixer/src/net/minemora/entitytrackerfixer/CheckTask.java b/EntityTrackerFixer/src/net/minemora/entitytrackerfixer/CheckTask.java index bb76e64..f7a265b 100644 --- a/EntityTrackerFixer/src/net/minemora/entitytrackerfixer/CheckTask.java +++ b/EntityTrackerFixer/src/net/minemora/entitytrackerfixer/CheckTask.java @@ -5,6 +5,7 @@ import java.util.Iterator; import java.util.List; import java.util.NoSuchElementException; import java.util.Set; +import java.util.UUID; import org.bukkit.Bukkit; import org.bukkit.Location; @@ -41,34 +42,35 @@ public class CheckTask extends BukkitRunnable { WorldServer ws = ((CraftWorld)Bukkit.getWorld(worldName)).getHandle(); ChunkProviderServer cps = ws.getChunkProvider(); - Set toRemove = new HashSet<>(); + Set toRemove = new HashSet<>(); Set trackAgain = new HashSet<>(); - Iterator it = UntrackedEntitiesCache.getInstance().getCache(worldName).iterator(); + Iterator it = UntrackedEntitiesCache.getInstance().getCache(worldName).values().iterator(); while (it.hasNext()) { UntrackedEntity ute = it.next(); net.minecraft.server.v1_14_R1.Entity nmsEnt = ute.getEntity(); + UUID uid = nmsEnt.getUniqueID(); if(cps.playerChunkMap.trackedEntities.containsKey(nmsEnt.getId())) { //System.out.println("removed (et contains): " + nmsEnt.getBukkitEntity().getType().name()); - toRemove.add(ute); + toRemove.add(uid); continue; } World world = nmsEnt.getBukkitEntity().getWorld(); Location loc = nmsEnt.getBukkitEntity().getLocation(); if(!Util.isChunkLoaded(ws, loc.getBlockX() >> 4, loc.getBlockZ() >> 4)) { //System.out.println("removed (unloaded chunk x:"+(loc.getBlockX() >> 4)+" z:"+(loc.getBlockZ() >> 4)+"): " + nmsEnt.getBukkitEntity().getType().name()); - UntrackedEntitiesCache.getInstance().addUFC(worldName, nmsEnt.getId()); - toRemove.add(ute); + UntrackedEntitiesCache.getInstance().addUFC(worldName, uid); + toRemove.add(uid); continue; } if(!worldName.equals(world.getName())) { //System.out.println("removed (different world): " + nmsEnt.getBukkitEntity().getType().name()); - toRemove.add(ute); + toRemove.add(uid); continue; } if(nmsEnt.getBukkitEntity().isDead()) { //System.out.println("removed (is dead): " + nmsEnt.getBukkitEntity().getType().name()); - toRemove.add(ute); + toRemove.add(uid); continue; } boolean track = false; @@ -94,7 +96,6 @@ public class CheckTask extends BukkitRunnable { } } if(track) { - //System.out.println("tracked again: " + nmsEnt.getBukkitEntity().getType().name()); trackAgain.add(nmsEnt); } } diff --git a/EntityTrackerFixer/src/net/minemora/entitytrackerfixer/EntityTrackerFixer.java b/EntityTrackerFixer/src/net/minemora/entitytrackerfixer/EntityTrackerFixer.java index 54be6d7..3e5bac7 100644 --- a/EntityTrackerFixer/src/net/minemora/entitytrackerfixer/EntityTrackerFixer.java +++ b/EntityTrackerFixer/src/net/minemora/entitytrackerfixer/EntityTrackerFixer.java @@ -2,6 +2,7 @@ package net.minemora.entitytrackerfixer; import org.bukkit.plugin.java.JavaPlugin; +import net.minemora.entitytrackerfixer.commands.CommandETF; import net.minemora.entitytrackerfixer.config.ConfigMain; import net.minemora.entitytrackerfixer.listener.ChunkEventListener; @@ -16,5 +17,6 @@ public class EntityTrackerFixer extends JavaPlugin { new UntrackerTask().runTaskTimer(this, ConfigMain.getUntrackTicks(), ConfigMain.getUntrackTicks()); new CheckTask().runTaskTimerAsynchronously(this, ConfigMain.getUntrackTicks() + 1, ConfigMain.getCheckFrequency()); getServer().getPluginManager().registerEvents(new ChunkEventListener(), this); + this.getCommand("etf").setExecutor(new CommandETF()); } } diff --git a/EntityTrackerFixer/src/net/minemora/entitytrackerfixer/TrackedWorld.java b/EntityTrackerFixer/src/net/minemora/entitytrackerfixer/TrackedWorld.java index 270714d..b0ea1c3 100644 --- a/EntityTrackerFixer/src/net/minemora/entitytrackerfixer/TrackedWorld.java +++ b/EntityTrackerFixer/src/net/minemora/entitytrackerfixer/TrackedWorld.java @@ -1,51 +1,57 @@ package net.minemora.entitytrackerfixer; +import java.util.Map; import java.util.Set; +import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; public class TrackedWorld { private final String worldName; - private Set cache = ConcurrentHashMap.newKeySet(); - private Set unloadedFromChunkCache = ConcurrentHashMap.newKeySet(); + private Map cache = new ConcurrentHashMap<>(); + private Set unloadedFromChunkCache = ConcurrentHashMap.newKeySet(); public TrackedWorld(String worldName) { this.worldName = worldName; } public void add(net.minecraft.server.v1_14_R1.Entity entity) { - cache.add(new UntrackedEntity(entity)); + cache.put(entity.getUniqueID(), new UntrackedEntity(entity)); } public void remove(UntrackedEntity ute) { - cache.remove(ute); + cache.remove(ute.getUniqueID()); } - public void removeAll(Set toRemove) { - cache.removeAll(toRemove); + public boolean contains(UUID uid) { + return cache.containsKey(uid); + } + + public void removeAll(Set toRemove) { + cache.keySet().removeAll(toRemove); } public boolean isEmpty(String worldName) { return cache.isEmpty(); } - public Set getCache() { + public Map getCache() { return cache; } - public void addUFC(int i) { - unloadedFromChunkCache.add(i); + public void addUFC(UUID uid) { + unloadedFromChunkCache.add(uid); } - public void removeUFC(int i) { - unloadedFromChunkCache.remove(i); + public void removeUFC(UUID uid) { + unloadedFromChunkCache.remove(uid); } - public boolean containsUFC(int i) { - return unloadedFromChunkCache.contains(i); + public boolean containsUFC(UUID uid) { + return unloadedFromChunkCache.contains(uid); } - public Set getUnloadedFromChunkCache() { + public Set getUnloadedFromChunkCache() { return unloadedFromChunkCache; } diff --git a/EntityTrackerFixer/src/net/minemora/entitytrackerfixer/UntrackedEntitiesCache.java b/EntityTrackerFixer/src/net/minemora/entitytrackerfixer/UntrackedEntitiesCache.java index 03b037f..ba7c719 100644 --- a/EntityTrackerFixer/src/net/minemora/entitytrackerfixer/UntrackedEntitiesCache.java +++ b/EntityTrackerFixer/src/net/minemora/entitytrackerfixer/UntrackedEntitiesCache.java @@ -1,8 +1,10 @@ package net.minemora.entitytrackerfixer; +import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; +import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; import net.minemora.entitytrackerfixer.config.ConfigMain; @@ -37,7 +39,15 @@ public final class UntrackedEntitiesCache { tw.remove(ute); } - public void removeAll(Set toRemove, String worldName) { + public boolean contains(UUID uid, String worldName) { + if(!trackedWorlds.containsKey(worldName)) { + return false; + } + TrackedWorld tw = trackedWorlds.get(worldName); + return tw.contains(uid); + } + + public void removeAll(Set toRemove, String worldName) { if(!trackedWorlds.containsKey(worldName)) { return; } @@ -52,40 +62,40 @@ public final class UntrackedEntitiesCache { return getCache(worldName).isEmpty(); } - public Set getCache(String worldName) { + public Map getCache(String worldName) { if(!trackedWorlds.containsKey(worldName)) { - return new HashSet(); + return new HashMap<>(); } TrackedWorld tw = trackedWorlds.get(worldName); return tw.getCache(); } - public void addUFC(String worldName, int i) { + public void addUFC(String worldName, UUID uid) { if(!trackedWorlds.containsKey(worldName)) { return; } TrackedWorld tw = trackedWorlds.get(worldName); - tw.addUFC(i); + tw.addUFC(uid); } - public void removeUFC(String worldName, int i) { + public void removeUFC(String worldName, UUID uid) { if(!trackedWorlds.containsKey(worldName)) { return; } TrackedWorld tw = trackedWorlds.get(worldName); - tw.removeUFC(i); + tw.removeUFC(uid); } - public boolean containsUFC(String worldName, int i) { + public boolean containsUFC(String worldName, UUID uid) { if(!trackedWorlds.containsKey(worldName)) { - return true; + return false; } - return getUnloadedFromChunkCache(worldName).contains(i); + return getUnloadedFromChunkCache(worldName).contains(uid); } - public Set getUnloadedFromChunkCache(String worldName) { + public Set getUnloadedFromChunkCache(String worldName) { if(!trackedWorlds.containsKey(worldName)) { - return new HashSet(); + return new HashSet(); } TrackedWorld tw = trackedWorlds.get(worldName); return tw.getUnloadedFromChunkCache(); diff --git a/EntityTrackerFixer/src/net/minemora/entitytrackerfixer/UntrackedEntity.java b/EntityTrackerFixer/src/net/minemora/entitytrackerfixer/UntrackedEntity.java index e52f224..5693abc 100644 --- a/EntityTrackerFixer/src/net/minemora/entitytrackerfixer/UntrackedEntity.java +++ b/EntityTrackerFixer/src/net/minemora/entitytrackerfixer/UntrackedEntity.java @@ -1,12 +1,16 @@ package net.minemora.entitytrackerfixer; +import java.util.UUID; + public class UntrackedEntity { private final net.minecraft.server.v1_14_R1.Entity entity; - private final int id; + private final UUID uniqueID; + private int id; public UntrackedEntity(net.minecraft.server.v1_14_R1.Entity entity) { this.entity = entity; + this.uniqueID = entity.getUniqueID(); this.id = entity.getId(); } @@ -14,7 +18,11 @@ public class UntrackedEntity { return entity; } - public int getId() { + public UUID getUniqueID() { + return uniqueID; + } + + private int getId() { return id; } diff --git a/EntityTrackerFixer/src/net/minemora/entitytrackerfixer/UntrackerTask.java b/EntityTrackerFixer/src/net/minemora/entitytrackerfixer/UntrackerTask.java index e7bde4f..fd64281 100644 --- a/EntityTrackerFixer/src/net/minemora/entitytrackerfixer/UntrackerTask.java +++ b/EntityTrackerFixer/src/net/minemora/entitytrackerfixer/UntrackerTask.java @@ -82,7 +82,7 @@ public class UntrackerTask extends BukkitRunnable { } Location loc = nmsEnt.getBukkitEntity().getLocation(); if(!Util.isChunkLoaded(ws, loc.getBlockX() >> 4, loc.getBlockZ() >> 4)) { - UntrackedEntitiesCache.getInstance().addUFC(worldName, nmsEnt.getId()); + UntrackedEntitiesCache.getInstance().addUFC(worldName, nmsEnt.getUniqueID()); } if(remove) { //System.out.println("untracked: " + nmsEnt.getBukkitEntity().getType().name()); @@ -111,6 +111,8 @@ public class UntrackerTask extends BukkitRunnable { if(ConfigMain.isLogToConsole()) { EntityTrackerFixer.plugin.getLogger().info("Untracked " + removed + " entities in " + worldName); } + + //System.out.println("cache now contains " + UntrackedEntitiesCache.getInstance().getCache(worldName).size() + " entities"); } public static boolean isRunning() { diff --git a/EntityTrackerFixer/src/net/minemora/entitytrackerfixer/commands/CommandETF.java b/EntityTrackerFixer/src/net/minemora/entitytrackerfixer/commands/CommandETF.java new file mode 100644 index 0000000..85c500b --- /dev/null +++ b/EntityTrackerFixer/src/net/minemora/entitytrackerfixer/commands/CommandETF.java @@ -0,0 +1,69 @@ +package net.minemora.entitytrackerfixer.commands; + +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.craftbukkit.v1_14_R1.CraftWorld; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; + +import net.minecraft.server.v1_14_R1.ChunkProviderServer; +import net.minecraft.server.v1_14_R1.WorldServer; +import net.minemora.entitytrackerfixer.UntrackedEntitiesCache; +import net.minemora.entitytrackerfixer.util.ChatUtils; + +public class CommandETF implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + if (!sender.hasPermission("etf.command")) { + return true; + } + if(args.length < 2) { + return true; + //TODO command list + } + if(args[0].equalsIgnoreCase("check")) { + if (!sender.hasPermission("etf.command.check")) { + return true; + } + if (!(sender instanceof Player)) { + sender.sendMessage(ChatUtils.format("&cOnly players can use this command")); + return true; + } + int r; + try { + r = Integer.parseInt(args[1]); + } catch (NumberFormatException e) { + sender.sendMessage(ChatUtils.format("&4" + args[1] + " &cis not a number")); + return true; + } + Player player = (Player)sender; + WorldServer ws = ((CraftWorld)player.getWorld()).getHandle(); + ChunkProviderServer cps = ws.getChunkProvider(); + int trackedCount = 0; + int untrackedCount = 0; + int cachedCount = 0; + for(Entity ent : player.getNearbyEntities(r, r, r)) { + if(cps.playerChunkMap.trackedEntities.containsKey(ent.getEntityId())) { + trackedCount++; + } + else { + untrackedCount++; + } + if(UntrackedEntitiesCache.getInstance().contains(ent.getUniqueId(), ent.getWorld().getName())) { + cachedCount++; + } + } + player.sendMessage(ChatUtils.format(new String[] { + "&bChecking entities in radius &f" + r, + " &f> &9Tracked Entities: &a" + trackedCount, + " &f> &9Untracked Entities &c" + untrackedCount, + " &f> &9Cached Entities &e" + cachedCount, + "&7(Untracked and cache should be the same number)" + })); + + } + return true; + } +} diff --git a/EntityTrackerFixer/src/net/minemora/entitytrackerfixer/listener/ChunkEventListener.java b/EntityTrackerFixer/src/net/minemora/entitytrackerfixer/listener/ChunkEventListener.java index 3e726f0..bb16831 100644 --- a/EntityTrackerFixer/src/net/minemora/entitytrackerfixer/listener/ChunkEventListener.java +++ b/EntityTrackerFixer/src/net/minemora/entitytrackerfixer/listener/ChunkEventListener.java @@ -19,9 +19,9 @@ public class ChunkEventListener implements Listener { return; } for(Entity entity : ch.getEntities()) { - if(UntrackedEntitiesCache.getInstance().containsUFC(ch.getWorld().getName(), entity.getEntityId())) { + if(UntrackedEntitiesCache.getInstance().containsUFC(ch.getWorld().getName(), entity.getUniqueId())) { UntrackedEntitiesCache.getInstance().add(((CraftEntity)entity).getHandle()); - UntrackedEntitiesCache.getInstance().removeUFC(ch.getWorld().getName(), entity.getEntityId()); + UntrackedEntitiesCache.getInstance().removeUFC(ch.getWorld().getName(), entity.getUniqueId()); } } } diff --git a/EntityTrackerFixer/src/net/minemora/entitytrackerfixer/util/ChatUtils.java b/EntityTrackerFixer/src/net/minemora/entitytrackerfixer/util/ChatUtils.java new file mode 100644 index 0000000..e0f0b00 --- /dev/null +++ b/EntityTrackerFixer/src/net/minemora/entitytrackerfixer/util/ChatUtils.java @@ -0,0 +1,44 @@ +package net.minemora.entitytrackerfixer.util; + +import java.util.List; +import java.util.stream.Collectors; + +import org.bukkit.ChatColor; +import org.bukkit.Location; + +public interface ChatUtils { + + static String format(String m) { + return ChatColor.translateAlternateColorCodes('&', m); + } + + static String[] format(String[] m) { + String[] result; + result = new String[m.length]; + for (int i = 0; i < m.length; i++) { + result[i] = ChatColor.translateAlternateColorCodes('&', m[i]); + } + return result; + } + + static String[] format(List m) { + String[] result; + result = new String[m.size()]; + for (int i = 0; i < m.size(); i++) { + result[i] = ChatColor.translateAlternateColorCodes('&', m.get(i)); + } + return result; + } + + static List formatList(List m) { + return m.stream().map(s -> ChatColor.translateAlternateColorCodes('&', s)).collect(Collectors.toList()); + } + + static String formatTime(int seconds) { + return String.format("%02d:%02d", seconds / 60, seconds % 60); + } + + static String formatLocation(Location loc) { + return "[x:" + loc.getBlockX() + ", y:" + loc.getBlockY() + ", z:" + loc.getBlockZ() + "]"; + } +} \ No newline at end of file