Browse Source

perf improvements and rupture improvements

nossr50 1 month ago
parent
commit
382b86ad34

+ 2 - 0
Changelog.txt

@@ -1,5 +1,7 @@
 Version 2.2.038
     Fix potion match failing for non-english locales
+    FoliaLib Performance improvements (thanks SirSalad)
+    Fixed situations where Rupture could never end which affected server performance
 
 Version 2.2.037
     Fixed bug where Alchemy was not matching potions correctly and producing incorrect results (Thanks TheBentoBox)

+ 1 - 1
pom.xml

@@ -464,7 +464,7 @@
         <dependency>
             <groupId>com.github.technicallycoded</groupId>
             <artifactId>FoliaLib</artifactId>
-            <version>dev-SNAPSHOT</version>
+            <version>main-SNAPSHOT</version>
             <scope>compile</scope>
         </dependency>
     </dependencies>

+ 12 - 8
src/main/java/com/gmail/nossr50/datatypes/player/McMMOPlayer.java

@@ -21,6 +21,7 @@ import com.gmail.nossr50.locale.LocaleLoader;
 import com.gmail.nossr50.mcMMO;
 import com.gmail.nossr50.party.ShareHandler;
 import com.gmail.nossr50.runnables.skills.AbilityDisableTask;
+import com.gmail.nossr50.runnables.skills.RuptureTask;
 import com.gmail.nossr50.runnables.skills.ToolLowerTask;
 import com.gmail.nossr50.skills.SkillManager;
 import com.gmail.nossr50.skills.acrobatics.AcrobaticsManager;
@@ -1144,14 +1145,17 @@ public class McMMOPlayer implements Identified {
      * @param syncSave if true, data is saved synchronously
      */
     public void logout(boolean syncSave) {
-        Player thisPlayer = getPlayer();
-        if (getPlayer().hasMetadata(MetadataConstants.METADATA_KEY_RUPTURE)) {
-            RuptureTaskMeta ruptureTaskMeta = (RuptureTaskMeta) getPlayer().getMetadata(MetadataConstants.METADATA_KEY_RUPTURE).get(0);
-
-            //Punish a logout
-            ruptureTaskMeta.getRuptureTimerTask().endRupture();
-            ruptureTaskMeta.getRuptureTimerTask().endRupture();
-            ruptureTaskMeta.getRuptureTimerTask().endRupture();
+        final Player thisPlayer = getPlayer();
+        if (getPlayer() != null && getPlayer().hasMetadata(MetadataConstants.METADATA_KEY_RUPTURE)) {
+            final RuptureTaskMeta ruptureTaskMeta
+                    = (RuptureTaskMeta) getPlayer().getMetadata(MetadataConstants.METADATA_KEY_RUPTURE).get(0);
+            if (ruptureTaskMeta != null) {
+                final RuptureTask ruptureTimerTask = ruptureTaskMeta.getRuptureTimerTask();
+                if(ruptureTimerTask != null) {
+                    ruptureTimerTask.cancel();
+                }
+                getPlayer().removeMetadata(MetadataConstants.METADATA_KEY_RUPTURE, mcMMO.p);
+            }
         }
 
         cleanup();

+ 2 - 2
src/main/java/com/gmail/nossr50/listeners/EntityListener.java

@@ -662,7 +662,7 @@ public class EntityListener implements Listener {
      */
     @EventHandler(priority = EventPriority.LOWEST)
     public void onEntityDeathLowest(EntityDeathEvent event) {
-        LivingEntity entity = event.getEntity();
+        final LivingEntity entity = event.getEntity();
 
         // Clear metadata for Slimes/Magma Cubes after transformation events take place, otherwise small spawned slimes will not have any tags
         if (TRANSFORMABLE_ENTITIES.contains(entity.getType())) {
@@ -680,7 +680,7 @@ public class EntityListener implements Listener {
      */
     @EventHandler(ignoreCancelled = true)
     public void onEntityDeath(EntityDeathEvent event) {
-        LivingEntity entity = event.getEntity();
+        final LivingEntity entity = event.getEntity();
 
         if (mcMMO.getTransientEntityTracker().isTransient(entity)) {
             mcMMO.getTransientEntityTracker().killSummonAndCleanMobFlags(entity, null, false);

+ 0 - 3
src/main/java/com/gmail/nossr50/listeners/PlayerListener.java

@@ -10,7 +10,6 @@ import com.gmail.nossr50.datatypes.skills.subskills.taming.CallOfTheWildType;
 import com.gmail.nossr50.events.McMMOReplaceVanillaTreasureEvent;
 import com.gmail.nossr50.locale.LocaleLoader;
 import com.gmail.nossr50.mcMMO;
-import com.gmail.nossr50.party.ShareHandler;
 import com.gmail.nossr50.runnables.MobHealthDisplayUpdaterTask;
 import com.gmail.nossr50.runnables.player.PlayerProfileLoadingTask;
 import com.gmail.nossr50.skills.fishing.FishingManager;
@@ -26,8 +25,6 @@ import com.gmail.nossr50.util.player.UserManager;
 import com.gmail.nossr50.util.scoreboards.ScoreboardManager;
 import com.gmail.nossr50.util.skills.RankUtils;
 import com.gmail.nossr50.util.skills.SkillUtils;
-import com.gmail.nossr50.util.sounds.SoundManager;
-import com.gmail.nossr50.util.sounds.SoundType;
 import com.gmail.nossr50.worldguard.WorldGuardManager;
 import com.gmail.nossr50.worldguard.WorldGuardUtils;
 import org.bukkit.Bukkit;

+ 16 - 0
src/main/java/com/gmail/nossr50/mcMMO.java

@@ -162,6 +162,7 @@ public class mcMMO extends JavaPlugin {
             //Folia lib plugin instance
             foliaLib = new FoliaLib(this);
             InvalidTickDelayNotifier.disableNotifications = true;
+            foliaPerformanceHack();
 
             setupFilePaths();
             generalConfig = new GeneralConfig(getDataFolder()); //Load before skillTools
@@ -315,6 +316,21 @@ public class mcMMO extends JavaPlugin {
         }
     }
 
+    private void foliaPerformanceHack() {
+        // Thanks SirSalad
+        // https://github.com/CraftYourTown/mcMMO/commit/2cffd64b127678411e20f0b8f9a3e3b87a649ee8
+        try {
+            com.tcoded.folialib.impl.FoliaImplementation setScheduler
+                    = new com.tcoded.folialib.impl.FoliaImplementation(foliaLib);
+            java.lang.reflect.Field FoliaLib$scheduler = FoliaLib.class.getDeclaredField("scheduler");
+            FoliaLib$scheduler.setAccessible(true);
+            FoliaLib$scheduler.set(foliaLib, setScheduler);
+            FoliaLib$scheduler.setAccessible(false);
+        } catch (NoSuchFieldException | IllegalAccessException e) {
+            getLogger().warning("Unable to apply performance tweaks to FoliaLib");
+        }
+    }
+
     public static PlayerLevelUtils getPlayerLevelUtils() {
         return playerLevelUtils;
     }

+ 31 - 22
src/main/java/com/gmail/nossr50/runnables/skills/RuptureTask.java

@@ -28,6 +28,9 @@ public class RuptureTask extends CancellableRunnable {
     private int damageTickTracker;
     private int animationTick;
     private final double pureTickDamage;
+    // failsafe to ensure Rupture always exits and does not run forever
+    private int totalTicks = 0;
+    private final int totalTickCeiling;
 
     /**
      * Constructor for the RuptureTask class.
@@ -41,7 +44,7 @@ public class RuptureTask extends CancellableRunnable {
         this.ruptureSource = ruptureSource;
         this.targetEntity = targetEntity;
         this.expireTick = mcMMO.p.getAdvancedConfig().getRuptureDurationSeconds(targetEntity instanceof Player) * 20;
-
+        this.totalTickCeiling = Math.min(this.expireTick, 200);
         this.ruptureTick = 0;
         this.damageTickTracker = 0;
         this.animationTick = ANIMATION_TICK_INTERVAL; //Play an animation right away
@@ -68,6 +71,14 @@ public class RuptureTask extends CancellableRunnable {
 
     @Override
     public void run() {
+        // always increment the fail-safe
+        totalTicks++;
+
+        if (totalTicks >= totalTickCeiling) {
+            this.cancel();
+            return;
+        }
+
         //Check validity
         if (targetEntity.isValid()) {
             ruptureTick += 1; //Advance rupture tick by 1.
@@ -78,7 +89,6 @@ public class RuptureTask extends CancellableRunnable {
             if (ruptureTick < expireTick) {
                 //Is it time to damage?
                 if (damageTickTracker >= DAMAGE_TICK_INTERVAL) {
-
                     damageTickTracker = 0; //Reset timer
                     if (applyRupture()) return;
 
@@ -92,8 +102,8 @@ public class RuptureTask extends CancellableRunnable {
                 endRupture();
             }
         } else {
-            targetEntity.removeMetadata(MetadataConstants.METADATA_KEY_RUPTURE, mcMMO.p);
             this.cancel(); //Task no longer needed
+            targetEntity.removeMetadata(MetadataConstants.METADATA_KEY_RUPTURE, mcMMO.p);
         }
     }
 
@@ -152,7 +162,7 @@ public class RuptureTask extends CancellableRunnable {
         ruptureTick = 0;
     }
 
-    public void endRupture() {
+    private void endRupture() {
         targetEntity.removeMetadata(MetadataConstants.METADATA_KEY_RUPTURE, mcMMO.p);
         this.cancel(); //Task no longer needed
     }
@@ -171,6 +181,20 @@ public class RuptureTask extends CancellableRunnable {
         return tickDamage;
     }
 
+    @Override
+    public final boolean equals(Object o) {
+        if (!(o instanceof RuptureTask that)) return false;
+
+        return ruptureSource.equals(that.ruptureSource) && targetEntity.equals(that.targetEntity);
+    }
+
+    @Override
+    public int hashCode() {
+        int result = ruptureSource.hashCode();
+        result = 31 * result + targetEntity.hashCode();
+        return result;
+    }
+
     @Override
     public String toString() {
         return "RuptureTask{" +
@@ -179,25 +203,10 @@ public class RuptureTask extends CancellableRunnable {
                 ", expireTick=" + expireTick +
                 ", ruptureTick=" + ruptureTick +
                 ", damageTickTracker=" + damageTickTracker +
+                ", animationTick=" + animationTick +
                 ", pureTickDamage=" + pureTickDamage +
+                ", totalTicks=" + totalTicks +
+                ", totalTickCeiling=" + totalTickCeiling +
                 '}';
     }
-
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) return true;
-        if (o == null || getClass() != o.getClass()) return false;
-        RuptureTask that = (RuptureTask) o;
-        return expireTick == that.expireTick
-                && ruptureTick == that.ruptureTick
-                && damageTickTracker == that.damageTickTracker
-                && Double.compare(that.pureTickDamage, pureTickDamage) == 0
-                && Objects.equal(ruptureSource, that.ruptureSource) && Objects.equal(targetEntity, that.targetEntity);
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hashCode(ruptureSource, targetEntity, expireTick,
-                ruptureTick, damageTickTracker, pureTickDamage);
-    }
 }

+ 0 - 2
src/main/java/com/gmail/nossr50/skills/swords/SwordsManager.java

@@ -10,7 +10,6 @@ import com.gmail.nossr50.datatypes.skills.ToolType;
 import com.gmail.nossr50.mcMMO;
 import com.gmail.nossr50.runnables.skills.RuptureTask;
 import com.gmail.nossr50.skills.SkillManager;
-import com.gmail.nossr50.util.ItemUtils;
 import com.gmail.nossr50.util.MetadataConstants;
 import com.gmail.nossr50.util.Permissions;
 import com.gmail.nossr50.util.player.NotificationManager;
@@ -20,7 +19,6 @@ import com.gmail.nossr50.util.skills.RankUtils;
 import org.bukkit.entity.Entity;
 import org.bukkit.entity.LivingEntity;
 import org.bukkit.entity.Player;
-import org.bukkit.inventory.ItemStack;
 import org.jetbrains.annotations.NotNull;
 
 public class SwordsManager extends SkillManager {

+ 0 - 3
src/main/java/com/gmail/nossr50/util/ContainerMetadataUtils.java

@@ -1,8 +1,6 @@
 package com.gmail.nossr50.util;
 
 import com.gmail.nossr50.datatypes.player.McMMOPlayer;
-import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
-import com.gmail.nossr50.mcMMO;
 import com.gmail.nossr50.util.player.UserManager;
 import org.bukkit.Bukkit;
 import org.bukkit.ChatColor;
@@ -19,7 +17,6 @@ import java.util.UUID;
 
 import static com.gmail.nossr50.util.MetadataService.NSK_CONTAINER_UUID_LEAST_SIG;
 import static com.gmail.nossr50.util.MetadataService.NSK_CONTAINER_UUID_MOST_SIG;
-import static java.util.Objects.requireNonNull;
 
 public class ContainerMetadataUtils {
 

+ 0 - 2
src/test/java/com/gmail/nossr50/skills/excavation/ExcavationTest.java

@@ -9,8 +9,6 @@ import com.gmail.nossr50.util.skills.RankUtils;
 import org.bukkit.Location;
 import org.bukkit.Material;
 import org.bukkit.block.Block;
-import org.bukkit.block.BlockState;
-import org.bukkit.block.data.BlockData;
 import org.bukkit.entity.Player;
 import org.bukkit.inventory.ItemStack;
 import org.junit.jupiter.api.AfterEach;