Changed the way check tasks perform

This commit is contained in:
Esmorall 2019-09-07 16:22:44 -03:00
parent 582dd0a451
commit c5cc59ae7f
9 changed files with 7 additions and 441 deletions

View File

@ -1,16 +1,11 @@
package net.minemora.entitytrackerfixer;
import java.util.HashSet;
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;
import org.bukkit.World;
import org.bukkit.craftbukkit.v1_14_R1.CraftWorld;
import org.bukkit.craftbukkit.v1_14_R1.entity.CraftEntity;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitRunnable;
@ -18,7 +13,6 @@ import org.bukkit.scheduler.BukkitRunnable;
import net.minecraft.server.v1_14_R1.ChunkProviderServer;
import net.minecraft.server.v1_14_R1.WorldServer;
import net.minemora.entitytrackerfixer.config.ConfigMain;
import net.minemora.entitytrackerfixer.util.Util;
public class CheckTask extends BukkitRunnable {
@ -31,9 +25,6 @@ public class CheckTask extends BukkitRunnable {
if(Bukkit.getWorld(worldName) == null) {
continue;
}
if(UntrackedEntitiesCache.getInstance().isEmpty(worldName)) {
continue;
}
checkWorld(worldName);
}
}
@ -42,65 +33,16 @@ public class CheckTask extends BukkitRunnable {
WorldServer ws = ((CraftWorld)Bukkit.getWorld(worldName)).getHandle();
ChunkProviderServer cps = ws.getChunkProvider();
Set<UUID> toRemove = new HashSet<>();
Set<net.minecraft.server.v1_14_R1.Entity> trackAgain = new HashSet<>();
Iterator<UntrackedEntity> 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(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, uid);
toRemove.add(uid);
continue;
}
if(!worldName.equals(world.getName())) {
//System.out.println("removed (different world): " + nmsEnt.getBukkitEntity().getType().name());
toRemove.add(uid);
continue;
}
if(nmsEnt.getBukkitEntity().isDead()) {
//System.out.println("removed (is dead): " + nmsEnt.getBukkitEntity().getType().name());
toRemove.add(uid);
continue;
}
boolean track = false;
int d = ConfigMain.getTrackingRange();
List<Entity> ents;
try {
ents = nmsEnt.getBukkitEntity().getNearbyEntities(d, d, d);
} catch (NoSuchElementException e) {
continue;
}
if(ents.isEmpty()) {
continue;
}
for(Entity le : ents) {
if(le == null) {
continue;
}
if(le instanceof Player) {
track = true;
break;
int d = ConfigMain.getTrackingRange();
for(Player player : Bukkit.getWorld(worldName).getPlayers()) {
for(Entity ent : player.getNearbyEntities(d, d, d)) {
if(!cps.playerChunkMap.trackedEntities.containsKey(ent.getEntityId())) {
trackAgain.add(((CraftEntity)ent).getHandle());
}
}
if(track) {
trackAgain.add(nmsEnt);
}
}
UntrackedEntitiesCache.getInstance().removeAll(toRemove, worldName);
}
new BukkitRunnable() {
@Override

View File

@ -2,9 +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;
public class EntityTrackerFixer extends JavaPlugin {
@ -16,7 +14,5 @@ public class EntityTrackerFixer extends JavaPlugin {
ConfigMain.getInstance().setup(this);
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());
}
}

View File

@ -1,62 +0,0 @@
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 Map<UUID,UntrackedEntity> cache = new ConcurrentHashMap<>();
private Set<UUID> unloadedFromChunkCache = ConcurrentHashMap.newKeySet();
public TrackedWorld(String worldName) {
this.worldName = worldName;
}
public void add(net.minecraft.server.v1_14_R1.Entity entity) {
cache.put(entity.getUniqueID(), new UntrackedEntity(entity));
}
public void remove(UntrackedEntity ute) {
cache.remove(ute.getUniqueID());
}
public boolean contains(UUID uid) {
return cache.containsKey(uid);
}
public void removeAll(Set<UUID> toRemove) {
cache.keySet().removeAll(toRemove);
}
public boolean isEmpty(String worldName) {
return cache.isEmpty();
}
public Map<UUID,UntrackedEntity> getCache() {
return cache;
}
public void addUFC(UUID uid) {
unloadedFromChunkCache.add(uid);
}
public void removeUFC(UUID uid) {
unloadedFromChunkCache.remove(uid);
}
public boolean containsUFC(UUID uid) {
return unloadedFromChunkCache.contains(uid);
}
public Set<UUID> getUnloadedFromChunkCache() {
return unloadedFromChunkCache;
}
public String getWorldName() {
return worldName;
}
}

View File

@ -1,114 +0,0 @@
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;
public final class UntrackedEntitiesCache {
private static UntrackedEntitiesCache instance;
private Map<String,TrackedWorld> trackedWorlds = new ConcurrentHashMap<>();
private UntrackedEntitiesCache() {
for(String worldName : ConfigMain.getWorlds()) {
trackedWorlds.put(worldName, new TrackedWorld(worldName));
}
}
public void add(net.minecraft.server.v1_14_R1.Entity entity) {
String worldName = entity.getBukkitEntity().getWorld().getName();
if(!trackedWorlds.containsKey(worldName)) {
return;
}
TrackedWorld tw = trackedWorlds.get(worldName);
tw.add(entity);
}
public void remove(UntrackedEntity ute) {
String worldName = ute.getEntity().getBukkitEntity().getWorld().getName();
if(!trackedWorlds.containsKey(worldName)) {
return;
}
TrackedWorld tw = trackedWorlds.get(worldName);
tw.remove(ute);
}
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<UUID> toRemove, String worldName) {
if(!trackedWorlds.containsKey(worldName)) {
return;
}
TrackedWorld tw = trackedWorlds.get(worldName);
tw.removeAll(toRemove);
}
public boolean isEmpty(String worldName) {
if(!trackedWorlds.containsKey(worldName)) {
return true;
}
return getCache(worldName).isEmpty();
}
public Map<UUID,UntrackedEntity> getCache(String worldName) {
if(!trackedWorlds.containsKey(worldName)) {
return new HashMap<>();
}
TrackedWorld tw = trackedWorlds.get(worldName);
return tw.getCache();
}
public void addUFC(String worldName, UUID uid) {
if(!trackedWorlds.containsKey(worldName)) {
return;
}
TrackedWorld tw = trackedWorlds.get(worldName);
tw.addUFC(uid);
}
public void removeUFC(String worldName, UUID uid) {
if(!trackedWorlds.containsKey(worldName)) {
return;
}
TrackedWorld tw = trackedWorlds.get(worldName);
tw.removeUFC(uid);
}
public boolean containsUFC(String worldName, UUID uid) {
if(!trackedWorlds.containsKey(worldName)) {
return false;
}
return getUnloadedFromChunkCache(worldName).contains(uid);
}
public Set<UUID> getUnloadedFromChunkCache(String worldName) {
if(!trackedWorlds.containsKey(worldName)) {
return new HashSet<UUID>();
}
TrackedWorld tw = trackedWorlds.get(worldName);
return tw.getUnloadedFromChunkCache();
}
public static UntrackedEntitiesCache getInstance() {
if(instance == null) {
instance = new UntrackedEntitiesCache();
}
return instance;
}
public Map<String,TrackedWorld> getTrackedWorlds() {
return trackedWorlds;
}
}

View File

@ -1,48 +0,0 @@
package net.minemora.entitytrackerfixer;
import java.util.UUID;
public class UntrackedEntity {
private final net.minecraft.server.v1_14_R1.Entity entity;
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();
}
public net.minecraft.server.v1_14_R1.Entity getEntity() {
return entity;
}
public UUID getUniqueID() {
return uniqueID;
}
private int getId() {
return id;
}
@Override
public boolean equals(Object o) {
if (o == null) {
return false;
}
if (this == o) {
return true;
}
if ((o instanceof UntrackedEntity) && (((UntrackedEntity) o).getId() == this.id)) {
return true;
} else {
return false;
}
}
@Override
public int hashCode() {
return id;
}
}

View File

@ -5,7 +5,6 @@ import java.util.HashSet;
import java.util.Set;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.craftbukkit.v1_14_R1.CraftWorld;
import org.bukkit.scheduler.BukkitRunnable;
@ -16,7 +15,6 @@ import net.minecraft.server.v1_14_R1.WorldServer;
import net.minecraft.server.v1_14_R1.PlayerChunkMap.EntityTracker;
import net.minemora.entitytrackerfixer.config.ConfigMain;
import net.minemora.entitytrackerfixer.util.ReflectionUtils;
import net.minemora.entitytrackerfixer.util.Util;
public class UntrackerTask extends BukkitRunnable {
@ -80,15 +78,10 @@ public class UntrackerTask extends BukkitRunnable {
continue;
}
}
Location loc = nmsEnt.getBukkitEntity().getLocation();
if(!Util.isChunkLoaded(ws, loc.getBlockX() >> 4, loc.getBlockZ() >> 4)) {
UntrackedEntitiesCache.getInstance().addUFC(worldName, nmsEnt.getUniqueID());
}
if(remove) {
//System.out.println("untracked: " + nmsEnt.getBukkitEntity().getType().name());
toRemove.add(nmsEnt.getId());
removed++;
UntrackedEntitiesCache.getInstance().add(nmsEnt);
}
}
} catch (IllegalArgumentException | IllegalAccessException e) {

View File

@ -1,69 +0,0 @@
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;
}
}

View File

@ -1,28 +0,0 @@
package net.minemora.entitytrackerfixer.listener;
import org.bukkit.Chunk;
import org.bukkit.craftbukkit.v1_14_R1.entity.CraftEntity;
import org.bukkit.entity.Entity;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.world.ChunkLoadEvent;
import net.minemora.entitytrackerfixer.UntrackedEntitiesCache;
import net.minemora.entitytrackerfixer.config.ConfigMain;
public class ChunkEventListener implements Listener {
@EventHandler
public void onChunkLoad(ChunkLoadEvent event) {
Chunk ch = event.getChunk();
if(!ConfigMain.getWorlds().contains(ch.getWorld().getName())) {
return;
}
for(Entity entity : ch.getEntities()) {
if(UntrackedEntitiesCache.getInstance().containsUFC(ch.getWorld().getName(), entity.getUniqueId())) {
UntrackedEntitiesCache.getInstance().add(((CraftEntity)entity).getHandle());
UntrackedEntitiesCache.getInstance().removeUFC(ch.getWorld().getName(), entity.getUniqueId());
}
}
}
}

View File

@ -1,44 +0,0 @@
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<String> 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<String> formatList(List<String> 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() + "]";
}
}