Compare commits

..

3 Commits

Author SHA1 Message Date
nossr50
5e9ee1e275 2.2.038 2025-06-06 18:58:57 -07:00
nossr50
12127ff25b spigot safeguards 2025-06-06 18:57:44 -07:00
nossr50
382b86ad34 perf improvements and rupture improvements 2025-06-06 18:43:41 -07:00
10 changed files with 82 additions and 44 deletions

View File

@ -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)

View File

@ -2,7 +2,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>com.gmail.nossr50.mcMMO</groupId>
<artifactId>mcMMO</artifactId>
<version>2.2.038-SNAPSHOT</version>
<version>2.2.038</version>
<name>mcMMO</name>
<url>https://github.com/mcMMO-Dev/mcMMO</url>
<scm>
@ -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>

View File

@ -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();

View File

@ -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);

View File

@ -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;

View File

@ -49,6 +49,7 @@ import com.gmail.nossr50.util.skills.SkillTools;
import com.gmail.nossr50.util.upgrade.UpgradeManager;
import com.gmail.nossr50.worldguard.WorldGuardManager;
import com.tcoded.folialib.FoliaLib;
import com.tcoded.folialib.impl.FoliaImplementation;
import com.tcoded.folialib.util.InvalidTickDelayNotifier;
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
import net.shatteredlands.shatt.backup.ZipLibrary;
@ -162,6 +163,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 +317,37 @@ public class mcMMO extends JavaPlugin {
}
}
private void foliaPerformanceHack() {
// Spigot can't use this optimization
if (!hasGlobalRegionScheduler()) {
return;
}
// Thanks SirSalad
// https://github.com/CraftYourTown/mcMMO/commit/2cffd64b127678411e20f0b8f9a3e3b87a649ee8
try {
final FoliaImplementation setScheduler = new FoliaImplementation(foliaLib);
final java.lang.reflect.Field scheduler = FoliaLib.class.getDeclaredField("scheduler");
scheduler.setAccessible(true);
scheduler.set(foliaLib, setScheduler);
scheduler.setAccessible(false);
} catch (NoSuchFieldException | IllegalAccessException e) {
getLogger().warning("Unexpected exception when attempting to apply performance tweaks to FoliaLib");
}
}
private static boolean hasGlobalRegionScheduler() {
try {
// No parameters empty Class<?> array
Bukkit.getServer()
.getClass()
.getMethod("getGlobalRegionScheduler");
return true; // Method is present
} catch (NoSuchMethodException ignored) {
return false; // Not running on Paper/Folia
}
}
public static PlayerLevelUtils getPlayerLevelUtils() {
return playerLevelUtils;
}

View File

@ -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);
}
}

View File

@ -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 {

View File

@ -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 {

View File

@ -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;