Added new experimental option (disable tick for untracked entities)
This commit is contained in:
parent
7436048976
commit
04940534bc
|
@ -8,9 +8,12 @@
|
||||||
#Log when the plugin untrack entities
|
#Log when the plugin untrack entities
|
||||||
log-to-console: true
|
log-to-console: true
|
||||||
|
|
||||||
|
#disable tick for untracked entities
|
||||||
|
disable-tick-for-untracked-entities: true
|
||||||
|
|
||||||
#How many ticks between untrack process
|
#How many ticks between untrack process
|
||||||
#The untrack process will check for untracked entities by players but still by the server, and untrack them.
|
#The untrack process will check for untracked entities by players but still by the server, and untrack them.
|
||||||
untrack-ticks: 600
|
untrack-ticks: 400
|
||||||
|
|
||||||
#if tps are not below this value, the task will not perform the untrack and it will wait for the next run
|
#if tps are not below this value, the task will not perform the untrack and it will wait for the next run
|
||||||
tps-limit: 18.5
|
tps-limit: 18.5
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
name: EntityTrackerFixer
|
name: EntityTrackerFixer
|
||||||
main: net.minemora.entitytrackerfixer.EntityTrackerFixer
|
main: net.minemora.entitytrackerfixer.EntityTrackerFixer
|
||||||
version: 1.1
|
version: 1.2.0
|
||||||
api-version: 1.14
|
api-version: 1.14
|
||||||
author: Esmorall
|
author: Esmorall
|
||||||
commands:
|
commands:
|
||||||
|
|
|
@ -13,6 +13,7 @@ import org.bukkit.scheduler.BukkitRunnable;
|
||||||
import net.minecraft.server.v1_14_R1.ChunkProviderServer;
|
import net.minecraft.server.v1_14_R1.ChunkProviderServer;
|
||||||
import net.minecraft.server.v1_14_R1.WorldServer;
|
import net.minecraft.server.v1_14_R1.WorldServer;
|
||||||
import net.minemora.entitytrackerfixer.config.ConfigMain;
|
import net.minemora.entitytrackerfixer.config.ConfigMain;
|
||||||
|
import net.minemora.entitytrackerfixer.entitytick.EntityTickManager;
|
||||||
|
|
||||||
public class CheckTask extends BukkitRunnable {
|
public class CheckTask extends BukkitRunnable {
|
||||||
|
|
||||||
|
@ -40,6 +41,9 @@ public class CheckTask extends BukkitRunnable {
|
||||||
for(Entity ent : player.getNearbyEntities(d, d, d)) {
|
for(Entity ent : player.getNearbyEntities(d, d, d)) {
|
||||||
if(!cps.playerChunkMap.trackedEntities.containsKey(ent.getEntityId())) {
|
if(!cps.playerChunkMap.trackedEntities.containsKey(ent.getEntityId())) {
|
||||||
trackAgain.add(((CraftEntity)ent).getHandle());
|
trackAgain.add(((CraftEntity)ent).getHandle());
|
||||||
|
if(ConfigMain.isDisableTickUntracked()) {
|
||||||
|
EntityTickManager.getInstance().enableTicking(((CraftEntity)ent).getHandle(), worldName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,11 @@
|
||||||
package net.minemora.entitytrackerfixer;
|
package net.minemora.entitytrackerfixer;
|
||||||
|
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.plugin.java.JavaPlugin;
|
import org.bukkit.plugin.java.JavaPlugin;
|
||||||
|
|
||||||
import net.minemora.entitytrackerfixer.config.ConfigMain;
|
import net.minemora.entitytrackerfixer.config.ConfigMain;
|
||||||
|
import net.minemora.entitytrackerfixer.entitytick.EntityTickManager;
|
||||||
|
import net.minemora.entitytrackerfixer.entitytick.EntityTickWorldCache;
|
||||||
|
|
||||||
public class EntityTrackerFixer extends JavaPlugin {
|
public class EntityTrackerFixer extends JavaPlugin {
|
||||||
|
|
||||||
|
@ -12,6 +15,14 @@ public class EntityTrackerFixer extends JavaPlugin {
|
||||||
public void onEnable() {
|
public void onEnable() {
|
||||||
plugin = this;
|
plugin = this;
|
||||||
ConfigMain.getInstance().setup(this);
|
ConfigMain.getInstance().setup(this);
|
||||||
|
if(ConfigMain.isDisableTickUntracked()) {
|
||||||
|
for(String worldName : ConfigMain.getWorlds()) {
|
||||||
|
if(Bukkit.getWorld(worldName) == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
EntityTickManager.getInstance().getCache().put(worldName, new EntityTickWorldCache(worldName));
|
||||||
|
}
|
||||||
|
}
|
||||||
new UntrackerTask().runTaskTimer(this, ConfigMain.getUntrackTicks(), ConfigMain.getUntrackTicks());
|
new UntrackerTask().runTaskTimer(this, ConfigMain.getUntrackTicks(), ConfigMain.getUntrackTicks());
|
||||||
new CheckTask().runTaskTimer(this, ConfigMain.getUntrackTicks() + 1, ConfigMain.getCheckFrequency());
|
new CheckTask().runTaskTimer(this, ConfigMain.getUntrackTicks() + 1, ConfigMain.getCheckFrequency());
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@ import net.minecraft.server.v1_14_R1.MinecraftServer;
|
||||||
import net.minecraft.server.v1_14_R1.WorldServer;
|
import net.minecraft.server.v1_14_R1.WorldServer;
|
||||||
import net.minecraft.server.v1_14_R1.PlayerChunkMap.EntityTracker;
|
import net.minecraft.server.v1_14_R1.PlayerChunkMap.EntityTracker;
|
||||||
import net.minemora.entitytrackerfixer.config.ConfigMain;
|
import net.minemora.entitytrackerfixer.config.ConfigMain;
|
||||||
|
import net.minemora.entitytrackerfixer.entitytick.EntityTickManager;
|
||||||
import net.minemora.entitytrackerfixer.util.ReflectionUtils;
|
import net.minemora.entitytrackerfixer.util.ReflectionUtils;
|
||||||
|
|
||||||
public class UntrackerTask extends BukkitRunnable {
|
public class UntrackerTask extends BukkitRunnable {
|
||||||
|
@ -90,6 +91,9 @@ public class UntrackerTask extends BukkitRunnable {
|
||||||
|
|
||||||
for(int id : toRemove) {
|
for(int id : toRemove) {
|
||||||
cps.playerChunkMap.trackedEntities.remove(id);
|
cps.playerChunkMap.trackedEntities.remove(id);
|
||||||
|
if(ConfigMain.isDisableTickUntracked()) {
|
||||||
|
EntityTickManager.getInstance().disableTicking(id, worldName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -14,6 +14,7 @@ public final class ConfigMain extends Config {
|
||||||
private static int trackingRange;
|
private static int trackingRange;
|
||||||
private static double minTps;
|
private static double minTps;
|
||||||
private static boolean logToConsole = true;
|
private static boolean logToConsole = true;
|
||||||
|
private static boolean disableTickUntracked = true;
|
||||||
private static List<String> worlds = new ArrayList<>();
|
private static List<String> worlds = new ArrayList<>();
|
||||||
|
|
||||||
private ConfigMain() {
|
private ConfigMain() {
|
||||||
|
@ -28,6 +29,7 @@ public final class ConfigMain extends Config {
|
||||||
minTps = getConfig().getDouble("tps-limit", 18.5);
|
minTps = getConfig().getDouble("tps-limit", 18.5);
|
||||||
worlds = getConfig().getStringList("worlds");
|
worlds = getConfig().getStringList("worlds");
|
||||||
logToConsole = getConfig().getBoolean("log-to-console", true);
|
logToConsole = getConfig().getBoolean("log-to-console", true);
|
||||||
|
disableTickUntracked = getConfig().getBoolean("disable-tick-for-untracked-entities", true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static FileConfiguration get() {
|
public static FileConfiguration get() {
|
||||||
|
@ -69,4 +71,8 @@ public final class ConfigMain extends Config {
|
||||||
public static boolean isLogToConsole() {
|
public static boolean isLogToConsole() {
|
||||||
return logToConsole;
|
return logToConsole;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean isDisableTickUntracked() {
|
||||||
|
return disableTickUntracked;
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,88 @@
|
||||||
|
package net.minemora.entitytrackerfixer.entitytick;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Timer;
|
||||||
|
import java.util.TimerTask;
|
||||||
|
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.craftbukkit.v1_14_R1.CraftWorld;
|
||||||
|
|
||||||
|
import net.minecraft.server.v1_14_R1.WorldServer;
|
||||||
|
import net.minemora.entitytrackerfixer.UntrackerTask;
|
||||||
|
import net.minemora.entitytrackerfixer.util.ReflectionUtils;
|
||||||
|
|
||||||
|
public class EntityTickManager extends TimerTask {
|
||||||
|
|
||||||
|
private static Field tickingField;
|
||||||
|
|
||||||
|
static {
|
||||||
|
try {
|
||||||
|
tickingField = ReflectionUtils.getClassPrivateField(WorldServer.class, "ticking");
|
||||||
|
} catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static EntityTickManager instance;
|
||||||
|
|
||||||
|
private Map<String, EntityTickWorldCache> cache = new HashMap<>();
|
||||||
|
|
||||||
|
private Timer timer;
|
||||||
|
|
||||||
|
private EntityTickManager() {
|
||||||
|
this.timer = new Timer();
|
||||||
|
timer.schedule(this, 2069, 2069);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void disableTicking(int id, String worldName) {
|
||||||
|
cache.get(worldName).getToTick().remove(id);
|
||||||
|
cache.get(worldName).getToUntick().add(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void enableTicking(net.minecraft.server.v1_14_R1.Entity entity, String worldName) {
|
||||||
|
cache.get(worldName).getToUntick().remove(entity.getId());
|
||||||
|
cache.get(worldName).getToTick().put(entity.getId(), entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
if(UntrackerTask.isRunning()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for(String worldName : cache.keySet()) {
|
||||||
|
WorldServer ws = ((CraftWorld)Bukkit.getWorld(worldName)).getHandle();
|
||||||
|
try {
|
||||||
|
boolean ticking = tickingField.getBoolean(ws);
|
||||||
|
if(ticking) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
EntityTickWorldCache ewc = cache.get(worldName);
|
||||||
|
//System.out.println("unticking: " + ewc.getToUntick().size() + " entities, ticking again: " + ewc.getToTick().size() + " entities");
|
||||||
|
for(int i : ewc.getToUntick()) {
|
||||||
|
ws.entitiesById.remove(i);
|
||||||
|
}
|
||||||
|
ewc.getToUntick().clear();
|
||||||
|
for(int i : ewc.getToTick().keySet()) {
|
||||||
|
ws.entitiesById.put(i, ewc.getToTick().get(i));
|
||||||
|
}
|
||||||
|
ewc.getToTick().clear();
|
||||||
|
} catch (IllegalArgumentException | IllegalAccessException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static EntityTickManager getInstance() {
|
||||||
|
if(instance == null) {
|
||||||
|
instance = new EntityTickManager();
|
||||||
|
}
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, EntityTickWorldCache> getCache() {
|
||||||
|
return cache;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
package net.minemora.entitytrackerfixer.entitytick;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
public class EntityTickWorldCache {
|
||||||
|
|
||||||
|
private String worldName;
|
||||||
|
|
||||||
|
private Set<Integer> toUntick = new HashSet<>();
|
||||||
|
private Map<Integer, net.minecraft.server.v1_14_R1.Entity> toTick = new HashMap<>();
|
||||||
|
|
||||||
|
public EntityTickWorldCache(String worldName) {
|
||||||
|
this.worldName = worldName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<Integer> getToUntick() {
|
||||||
|
return toUntick;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<Integer, net.minecraft.server.v1_14_R1.Entity> getToTick() {
|
||||||
|
return toTick;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getWorldName() {
|
||||||
|
return worldName;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue