1.16.2 update

This commit is contained in:
Esmorall 2020-08-25 13:50:57 -03:00
parent f7395e7954
commit 7e07cde16d
9 changed files with 334 additions and 4 deletions

View File

@ -1,6 +1,6 @@
name: EntityTrackerFixer
main: net.minemora.entitytrackerfixer.EntityTrackerFixer
version: 1.3.1
version: 1.3.2
softdepend: [Vault]
api-version: 1.14
author: Esmorall

View File

@ -35,7 +35,7 @@ public class UntrackerTask extends BukkitRunnable {
}
}
@SuppressWarnings("deprecation")
@SuppressWarnings({ "deprecation", "resource" })
@Override
public void run() {
if(MinecraftServer.getServer().recentTps[0] > ConfigMain.getMinTps()) {

View File

@ -35,7 +35,7 @@ public class UntrackerTask extends BukkitRunnable {
}
}
@SuppressWarnings("deprecation")
@SuppressWarnings({ "deprecation", "resource" })
@Override
public void run() {
if(MinecraftServer.getServer().recentTps[0] > ConfigMain.getMinTps()) {

View File

@ -36,7 +36,7 @@ public class UntrackerTask extends BukkitRunnable {
}
}
@SuppressWarnings("deprecation")
@SuppressWarnings({ "deprecation", "resource" })
@Override
public void run() {
if(MinecraftServer.getServer().recentTps[0] > ConfigMain.getMinTps()) {

View File

@ -0,0 +1,48 @@
package net.minemora.entitytrackerfixer.v1_16_R2;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Set;
import net.minecraft.server.v1_16_R2.ChunkProviderServer;
import net.minecraft.server.v1_16_R2.PlayerChunkMap;
import net.minemora.entitytrackerfixer.util.ReflectionUtils;
public final class NMSEntityTracker {
private static Method addEntityMethod;
private static Method removeEntityMethod;
static {
try {
addEntityMethod = ReflectionUtils.getPrivateMethod(PlayerChunkMap.class, "addEntity",
new Class[] {net.minecraft.server.v1_16_R2.Entity.class});
removeEntityMethod = ReflectionUtils.getPrivateMethod(PlayerChunkMap.class, "removeEntity",
new Class[] {net.minecraft.server.v1_16_R2.Entity.class});
} catch (NoSuchMethodException | SecurityException | IllegalArgumentException e) {
e.printStackTrace();
}
}
private NMSEntityTracker() {}
public static void trackEntities(ChunkProviderServer cps, Set<net.minecraft.server.v1_16_R2.Entity> trackList) {
try {
for(net.minecraft.server.v1_16_R2.Entity entity : trackList) {
addEntityMethod.invoke(cps.playerChunkMap, entity);
}
} catch (SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
e.printStackTrace();
}
}
public static void untrackEntities(ChunkProviderServer cps, Set<net.minecraft.server.v1_16_R2.Entity> untrackList) {
try {
for(net.minecraft.server.v1_16_R2.Entity entity : untrackList) {
removeEntityMethod.invoke(cps.playerChunkMap, entity);
}
} catch (SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
e.printStackTrace();
}
}
}

View File

@ -0,0 +1,23 @@
package net.minemora.entitytrackerfixer.v1_16_R2;
import org.bukkit.plugin.Plugin;
import org.bukkit.scheduler.BukkitTask;
import net.minemora.entitytrackerfixer.config.ConfigMain;
import net.minemora.entitytrackerfixer.nms.NMS;
import net.minemora.entitytrackerfixer.v1_16_R2.tasks.CheckTask;
import net.minemora.entitytrackerfixer.v1_16_R2.tasks.UntrackerTask;
public class NMSHandler implements NMS {
@Override
public BukkitTask startUntrackerTask(Plugin plugin) {
return new UntrackerTask().runTaskTimer(plugin, ConfigMain.getUntrackTicks(), ConfigMain.getUntrackTicks());
}
@Override
public BukkitTask startUCheckTask(Plugin plugin) {
return new CheckTask().runTaskTimer(plugin, ConfigMain.getUntrackTicks() + 1, ConfigMain.getCheckFrequency());
}
}

View File

@ -0,0 +1,72 @@
package net.minemora.entitytrackerfixer.v1_16_R2.entityTick;
import java.util.Set;
import org.bukkit.craftbukkit.v1_16_R2.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.minecraft.server.v1_16_R2.EntityInsentient;
import net.minecraft.server.v1_16_R2.MinecraftServer;
import net.minemora.entitytrackerfixer.EntityTrackerFixer;
public class EntityTickManager implements Listener {
private static EntityTickManager instance;
private EntityTickManager() {
EntityTrackerFixer.plugin.getServer().getPluginManager().registerEvents(this, EntityTrackerFixer.plugin);
}
public void disableTicking(net.minecraft.server.v1_16_R2.Entity entity) {
if(entity == null) {
return;
}
if(!entity.valid) {
return;
}
entity.activatedTick = -2147483648L;
if(entity instanceof EntityInsentient) {
//System.out.println("disable tick for insentient entity currently aware is = " + ((EntityInsentient)entity).aware + " should be true");
((EntityInsentient)entity).aware = false;
}
}
public void enableTicking(Set<net.minecraft.server.v1_16_R2.Entity> entities) {
for(net.minecraft.server.v1_16_R2.Entity entity : entities) {
if(entity == null) {
continue;
}
if(!entity.valid) {
continue;
}
entity.activatedTick = MinecraftServer.currentTick;
if(entity instanceof EntityInsentient) {
//System.out.println("enabling tick for insentient entity currently aware is = " + ((EntityInsentient)entity).aware + " should be false");
((EntityInsentient)entity).aware = true;
}
}
}
@EventHandler
public void onChunkLoad(ChunkLoadEvent event) {
for(Entity entity : event.getChunk().getEntities()) {
net.minecraft.server.v1_16_R2.Entity nms = ((CraftEntity)entity).getHandle();
if(nms instanceof EntityInsentient) {
if(!((EntityInsentient)nms).aware) {
((EntityInsentient)nms).aware = true;
}
}
}
}
public static EntityTickManager getInstance() {
if(instance == null) {
instance = new EntityTickManager();
}
return instance;
}
}

View File

@ -0,0 +1,64 @@
package net.minemora.entitytrackerfixer.v1_16_R2.tasks;
import java.util.HashSet;
import java.util.Set;
import org.bukkit.Bukkit;
import org.bukkit.World;
import org.bukkit.craftbukkit.v1_16_R2.CraftWorld;
import org.bukkit.craftbukkit.v1_16_R2.entity.CraftEntity;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitRunnable;
import net.minecraft.server.v1_16_R2.ChunkProviderServer;
import net.minecraft.server.v1_16_R2.WorldServer;
import net.minemora.entitytrackerfixer.config.ConfigMain;
import net.minemora.entitytrackerfixer.v1_16_R2.NMSEntityTracker;
import net.minemora.entitytrackerfixer.v1_16_R2.entityTick.EntityTickManager;
public class CheckTask extends BukkitRunnable {
@Override
public void run() {
if(UntrackerTask.isRunning()) {
return;
}
if(ConfigMain.isEnableOnAllWorlds()) {
for(World world : Bukkit.getWorlds()) {
checkWorld(world.getName());
}
}
else {
for(String worldName : ConfigMain.getWorlds()) {
if(Bukkit.getWorld(worldName) == null) {
continue;
}
checkWorld(worldName);
}
}
}
public void checkWorld(String worldName) {
WorldServer ws = ((CraftWorld)Bukkit.getWorld(worldName)).getHandle();
ChunkProviderServer cps = ws.getChunkProvider();
Set<net.minecraft.server.v1_16_R2.Entity> trackAgain = new HashSet<>();
int d = ConfigMain.getTrackingRange();
for(Player player : Bukkit.getWorld(worldName).getPlayers()) {
for(Entity ent : player.getNearbyEntities(d, d, d)) {
net.minecraft.server.v1_16_R2.Entity nms = ((CraftEntity)ent).getHandle();
if(cps.playerChunkMap.trackedEntities.containsKey(nms.getId()) || !nms.valid) {
continue;
}
trackAgain.add(nms);
}
}
NMSEntityTracker.trackEntities(cps, trackAgain);
if(ConfigMain.isDisableTickUntracked()) {
EntityTickManager.getInstance().enableTicking(trackAgain);
}
}
}

View File

@ -0,0 +1,123 @@
package net.minemora.entitytrackerfixer.v1_16_R2.tasks;
import java.lang.reflect.Field;
import java.util.HashSet;
import java.util.Set;
import org.bukkit.Bukkit;
import org.bukkit.World;
import org.bukkit.craftbukkit.v1_16_R2.CraftWorld;
import org.bukkit.scheduler.BukkitRunnable;
import net.minecraft.server.v1_16_R2.ChunkProviderServer;
import net.minecraft.server.v1_16_R2.EntityArmorStand;
import net.minecraft.server.v1_16_R2.EntityComplexPart;
import net.minecraft.server.v1_16_R2.EntityEnderDragon;
import net.minecraft.server.v1_16_R2.EntityPlayer;
import net.minecraft.server.v1_16_R2.MinecraftServer;
import net.minecraft.server.v1_16_R2.WorldServer;
import net.minecraft.server.v1_16_R2.PlayerChunkMap.EntityTracker;
import net.minemora.entitytrackerfixer.EntityTrackerFixer;
import net.minemora.entitytrackerfixer.config.ConfigMain;
import net.minemora.entitytrackerfixer.util.ReflectionUtils;
import net.minemora.entitytrackerfixer.v1_16_R2.entityTick.EntityTickManager;
public class UntrackerTask extends BukkitRunnable {
private static boolean running = false;
private static Field trackerField;
static {
try {
trackerField = ReflectionUtils.getClassPrivateField(EntityTracker.class, "tracker");
} catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) {
e.printStackTrace();
}
}
@SuppressWarnings({ "deprecation", "resource" })
@Override
public void run() {
if(MinecraftServer.getServer().recentTps[0] > ConfigMain.getMinTps()) {
return;
}
running = true;
if(ConfigMain.isEnableOnAllWorlds()) {
for(World world : Bukkit.getWorlds()) {
untrackProcess(world.getName());
}
}
else {
for(String worldName : ConfigMain.getWorlds()) {
untrackProcess(worldName);
}
}
running = false;
}
private void untrackProcess(String worldName) {
if(Bukkit.getWorld(worldName) == null) {
return;
}
//Set<net.minecraft.server.v1_14_R2.Entity> toRemove = new HashSet<>();
Set<Integer> toRemove = new HashSet<>();
int removed = 0;
WorldServer ws = ((CraftWorld)Bukkit.getWorld(worldName)).getHandle();
ChunkProviderServer cps = ws.getChunkProvider();
try {
for(EntityTracker et : cps.playerChunkMap.trackedEntities.values()) {
net.minecraft.server.v1_16_R2.Entity nmsEnt = (net.minecraft.server.v1_16_R2.Entity) trackerField.get(et);
if(nmsEnt instanceof EntityPlayer || nmsEnt instanceof EntityEnderDragon || nmsEnt instanceof EntityComplexPart) {
continue;
}
if(nmsEnt instanceof EntityArmorStand && nmsEnt.getBukkitEntity().getCustomName() != null) {
continue;
}
boolean remove = false;
if(et.trackedPlayers.size() == 0) {
remove = true;
}
else if(et.trackedPlayers.size() == 1) {
for(EntityPlayer ep : et.trackedPlayers) {
if(!ep.getBukkitEntity().isOnline()) {
remove = true;
}
}
if(!remove) {
continue;
}
}
if(remove) {
//System.out.println("untracked: " + nmsEnt.getBukkitEntity().getType().name());
toRemove.add(nmsEnt.getId());
removed++;
}
}
} catch (IllegalArgumentException | IllegalAccessException e) {
e.printStackTrace();
}
for(int id : toRemove) {
cps.playerChunkMap.trackedEntities.remove(id);
if(ConfigMain.isDisableTickUntracked()) {
EntityTickManager.getInstance().disableTicking(ws.entitiesById.get(id));
}
}
if(ConfigMain.isLogToConsole()) {
if(removed > 0) {
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() {
return running;
}
}