diff --git a/pom.xml b/pom.xml index bf353a24..f4b882e2 100644 --- a/pom.xml +++ b/pom.xml @@ -156,7 +156,7 @@ com.github.Zrips Jobs - 4.17.2 + v5.2.2.3 provided @@ -173,6 +173,12 @@ system ${project.basedir}/jars/MyPet-3.11-SNAPSHOT-B1627.jar + + me.lucko + spark-api + 0.1-SNAPSHOT + provided + - + \ No newline at end of file diff --git a/src/main/java/uk/antiperson/stackmob/StackMob.java b/src/main/java/uk/antiperson/stackmob/StackMob.java index bfde8209..ee59d5d1 100644 --- a/src/main/java/uk/antiperson/stackmob/StackMob.java +++ b/src/main/java/uk/antiperson/stackmob/StackMob.java @@ -1,7 +1,6 @@ package uk.antiperson.stackmob; import org.bstats.bukkit.Metrics; -import org.bukkit.Bukkit; import org.bukkit.NamespacedKey; import org.bukkit.command.PluginCommand; import org.bukkit.event.Listener; @@ -14,6 +13,10 @@ import uk.antiperson.stackmob.entity.traits.TraitManager; import uk.antiperson.stackmob.hook.HookManager; import uk.antiperson.stackmob.listeners.*; +import uk.antiperson.stackmob.mspt.DummyMsptProvider; +import uk.antiperson.stackmob.mspt.MsptProvider; +import uk.antiperson.stackmob.mspt.PaperMsptProvider; +import uk.antiperson.stackmob.mspt.SparkMsptProvider; import uk.antiperson.stackmob.scheduler.BukkitScheduler; import uk.antiperson.stackmob.scheduler.FoliaScheduler; import uk.antiperson.stackmob.scheduler.Scheduler; @@ -39,6 +42,7 @@ public class StackMob extends JavaPlugin { private Updater updater; private ItemTools itemTools; private Scheduler scheduler; + private MsptProvider msptProvider; private boolean stepDamageError; @@ -114,7 +118,17 @@ public void onEnable() { case AVAILABLE: getLogger().info("A new version is currently available. (" + updateResult.getNewVersion() + ")"); break; } })); - + if (!Utilities.isPaper()) { + getLogger().warning("It has been detected that you are not using Paper (https://papermc.io)."); + getLogger().warning("StackMob makes use of Paper's API, which means you're missing out on features."); + } + if (this.getServer().getPluginManager().getPlugin("Spark") != null){ + this.msptProvider = new SparkMsptProvider(); + } else if (Utilities.isPaper()) { + this.msptProvider = new PaperMsptProvider(); + } else { + this.msptProvider = new DummyMsptProvider(); + } new Metrics(this, 522); } @@ -165,6 +179,10 @@ private void registerEvent(Class clazz) throws NoSuchMethodE getServer().getPluginManager().registerEvents(listener, this); } + public MsptProvider getMsptProvider() { + return msptProvider; + } + public EntityTranslation getEntityTranslation() { return entityTranslation; } diff --git a/src/main/java/uk/antiperson/stackmob/config/EntityConfig.java b/src/main/java/uk/antiperson/stackmob/config/EntityConfig.java index d8dadb8c..625596c8 100644 --- a/src/main/java/uk/antiperson/stackmob/config/EntityConfig.java +++ b/src/main/java/uk/antiperson/stackmob/config/EntityConfig.java @@ -117,6 +117,18 @@ public String getTagFormat() { return getString("display-name.format"); } + public boolean isMsptReactiveEnabled() { + return getBoolean("mspt-reactive.enabled"); + } + + public double getMsptReactiveTriggerThreshold() { + return getDouble("mspt-reactive.trigger-mspt-threshold"); + } + + public double getMsptReactiveUntriggerThreshold() { + return getDouble("mspt-reactive.untrigger-mspt-threshold"); + } + public int getTagThreshold() { return getInt( "display-name.threshold"); } diff --git a/src/main/java/uk/antiperson/stackmob/mspt/DummyMsptProvider.java b/src/main/java/uk/antiperson/stackmob/mspt/DummyMsptProvider.java new file mode 100644 index 00000000..cefc8914 --- /dev/null +++ b/src/main/java/uk/antiperson/stackmob/mspt/DummyMsptProvider.java @@ -0,0 +1,17 @@ +package uk.antiperson.stackmob.mspt; + +public class DummyMsptProvider extends MsptProvider { + + @Override + public double getMspt() { + return 0; + } + + @Override + public void setUnderLoad(boolean underLoad) { } + + @Override + public boolean isUnderLoad() { + return false; + } +} diff --git a/src/main/java/uk/antiperson/stackmob/mspt/MsptProvider.java b/src/main/java/uk/antiperson/stackmob/mspt/MsptProvider.java new file mode 100644 index 00000000..e2eb3e47 --- /dev/null +++ b/src/main/java/uk/antiperson/stackmob/mspt/MsptProvider.java @@ -0,0 +1,15 @@ +package uk.antiperson.stackmob.mspt; + +public abstract class MsptProvider { + + private boolean underLoad; + + public abstract double getMspt(); + public void setUnderLoad(boolean underLoad) { + this.underLoad = underLoad; + } + public boolean isUnderLoad() { + return this.underLoad; + } + +} diff --git a/src/main/java/uk/antiperson/stackmob/mspt/PaperMsptProvider.java b/src/main/java/uk/antiperson/stackmob/mspt/PaperMsptProvider.java new file mode 100644 index 00000000..dd649dee --- /dev/null +++ b/src/main/java/uk/antiperson/stackmob/mspt/PaperMsptProvider.java @@ -0,0 +1,11 @@ +package uk.antiperson.stackmob.mspt; + +import org.bukkit.Bukkit; + +public class PaperMsptProvider extends MsptProvider { + + @Override + public double getMspt() { + return Bukkit.getAverageTickTime(); + } +} diff --git a/src/main/java/uk/antiperson/stackmob/mspt/SparkMsptProvider.java b/src/main/java/uk/antiperson/stackmob/mspt/SparkMsptProvider.java new file mode 100644 index 00000000..71154f0d --- /dev/null +++ b/src/main/java/uk/antiperson/stackmob/mspt/SparkMsptProvider.java @@ -0,0 +1,22 @@ +package uk.antiperson.stackmob.mspt; + +import me.lucko.spark.api.Spark; +import me.lucko.spark.api.SparkProvider; +import me.lucko.spark.api.statistic.StatisticWindow; + +public class SparkMsptProvider extends MsptProvider { + + private final Spark spark; + + public SparkMsptProvider(){ + this.spark = SparkProvider.get(); + } + + @Override + public double getMspt() { + if(this.spark.mspt() == null){ + return 0; + } + return this.spark.mspt().poll(StatisticWindow.MillisPerTick.SECONDS_10).mean(); + } +} diff --git a/src/main/java/uk/antiperson/stackmob/tasks/MergeTask.java b/src/main/java/uk/antiperson/stackmob/tasks/MergeTask.java index 2debc0ea..33c99f43 100644 --- a/src/main/java/uk/antiperson/stackmob/tasks/MergeTask.java +++ b/src/main/java/uk/antiperson/stackmob/tasks/MergeTask.java @@ -18,7 +18,24 @@ public MergeTask(StackMob sm) { this.sm = sm; } - private void checkEntity(StackEntity original, boolean checkHasMoved, double checkHasMovedDistance) { + private void checkEntity(StackEntity original, boolean checkHasMoved, double checkHasMovedDistance, boolean checkMspt) { + if(checkMspt){ + if (sm.getMsptProvider().isUnderLoad()){ + if (sm.getMsptProvider().getMspt()<=original.getEntityConfig().getMsptReactiveUntriggerThreshold()){ + // mspt was under heavy load, but no longer is, reset its status and skip stacking + sm.getMsptProvider().setUnderLoad(false); + return; + } + } else { + if (sm.getMsptProvider().getMspt()>=original.getEntityConfig().getMsptReactiveTriggerThreshold()){ + // mspt is considered to be under heavy load, set under load to keep hysteresis status + sm.getMsptProvider().setUnderLoad(true); + } else { + // mspt is lower than the trigger threshold, skip stacking + return; + } + } + } if (original.isWaiting()) { original.incrementWait(); return; @@ -101,8 +118,9 @@ private void removeEntity(StackEntity stackEntity) { public void run() { boolean checkHasMoved = sm.getMainConfig().getConfig().isCheckHasMoved(); double checkHasMovedDistance = sm.getMainConfig().getConfig().getCheckHasMovedDistance(); + boolean checkMspt = sm.getMainConfig().getConfig().isMsptReactiveEnabled(); for (StackEntity original : sm.getEntityManager().getStackEntities()) { - Runnable runnable = () -> checkEntity(original, checkHasMoved, checkHasMovedDistance); + Runnable runnable = () -> checkEntity(original, checkHasMoved, checkHasMovedDistance, checkMspt); if (Utilities.IS_FOLIA) { sm.getScheduler().runTask(original.getEntity(), runnable); } else { diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index c827d2be..43701383 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -301,6 +301,16 @@ wait-to-stack: - SPAWNER reasons-whitelist-invert: false +# Enable the system based on MSPT. The MSPT will be updated as often as stack.interval +# you should use paper or install Spark for this feature to work! (**) +mspt-reactive: + enabled: false + # Above what MSPT should the reactive mode be triggered? + trigger-mspt-threshold: 65.0 + # Below what MSPT should the reactive mode be untriggered? + untrigger-mspt-threshold: 45.0 + + # Enable/disable integration with other plugins. (*) hooks: # Allows the custom 'entity-stacking' flag to be used in worldguard regions. diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 4a5a519c..f3878ff9 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -3,7 +3,8 @@ main: uk.antiperson.stackmob.StackMob version: ${project.version} api-version: 1.16 folia-supported: true -softdepend: [WorldGuard, MythicMobs, ClearLag, MyPet, mcMMO, Jobs, Citizens] +depend: [ProtocolLib] +softdepend: [WorldGuard, MythicMobs, ClearLag, MyPet, mcMMO, Jobs, Citizens, Spark] author: antiPerson website: https://modrinth.com/plugin/stackmob description: A plugin that aims to improve performance by 'stacking' entities together, with attempts to preserve game mechanics.