From 5aa34ce37c9532e3c87080e95bc1f1f7c607ff0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erik=20Szab=C3=B3?= Date: Thu, 24 Oct 2024 13:17:08 +0200 Subject: [PATCH 1/8] What could go wrong? --- bukkit/build.gradle.kts | 2 + .../auraskills/bukkit/AuraSkills.java | 4 +- .../bukkit/commands/SkillCommands.java | 2 +- .../bukkit/commands/SkillsRootCommand.java | 2 +- .../bukkit/commands/StatsCommand.java | 4 +- .../bukkit/hooks/DecentHologramsHook.java | 2 +- .../bukkit/hooks/HolographicDisplaysHook.java | 2 +- .../hooks/mythicmobs/MythicMobsHook.java | 2 + .../bukkit/level/BukkitLevelManager.java | 8 +-- .../bukkit/listeners/CriticalHandler.java | 2 +- .../bukkit/scheduler/BukkitScheduler.java | 51 ++++++++++++++++--- .../bukkit/scheduler/BukkitTaskWrapper.java | 7 +-- .../skills/agility/AgilityAbilities.java | 4 +- .../skills/alchemy/AlchemyAbilities.java | 6 +-- .../skills/archery/ArcheryAbilities.java | 24 +++++---- .../skills/defense/DefenseAbilities.java | 2 +- .../skills/farming/FarmingAbilities.java | 2 +- .../bukkit/skills/farming/Replenish.java | 2 +- .../skills/fighting/FightingAbilities.java | 4 +- .../bukkit/skills/foraging/Treecapitator.java | 2 +- .../bukkit/source/BlockLeveler.java | 2 +- .../bukkit/source/BrewingLeveler.java | 2 +- .../bukkit/trait/HealthRegenTraits.java | 43 ++++++++-------- .../auraskills/bukkit/trait/HpTrait.java | 9 ++-- .../auraskills/bukkit/trait/LuckTrait.java | 7 +-- .../bukkit/trait/MovementSpeedTrait.java | 28 +++++----- .../auraskills/bukkit/ui/BossBarManager.java | 4 +- bukkit/src/main/resources/plugin.yml | 2 + 28 files changed, 145 insertions(+), 86 deletions(-) diff --git a/bukkit/build.gradle.kts b/bukkit/build.gradle.kts index 65c100df5..e694587e3 100644 --- a/bukkit/build.gradle.kts +++ b/bukkit/build.gradle.kts @@ -39,6 +39,7 @@ dependencies { implementation("org.bstats:bstats-bukkit:3.0.2") implementation("net.kyori:adventure-text-minimessage:4.16.0") implementation("net.kyori:adventure-platform-bukkit:4.3.3") + implementation("com.github.technicallycoded:FoliaLib:main-SNAPSHOT") compileOnly("org.jetbrains:annotations:24.1.0") compileOnly("org.spigotmc:spigot-api:1.21.3-R0.1-SNAPSHOT") compileOnly("me.clip:placeholderapi:2.11.6") @@ -81,6 +82,7 @@ tasks { relocate("net.querz", "dev.aurelium.auraskills.querz") relocate("com.archyx.polyglot", "dev.aurelium.auraskills.polyglot") relocate("org.atteo.evo.inflector", "dev.aurelium.auraskills.inflector") + relocate("com.tcoded.folialib", "dev.aurelium.auraskills.folialib") exclude("acf-*.properties") diff --git a/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/AuraSkills.java b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/AuraSkills.java index 7e64cbcfe..ff6c5beb7 100644 --- a/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/AuraSkills.java +++ b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/AuraSkills.java @@ -140,7 +140,7 @@ public class AuraSkills extends JavaPlugin implements AuraSkillsPlugin { private LeaderboardManager leaderboardManager; private BukkitUiProvider uiProvider; private RewardManager rewardManager; - private Scheduler scheduler; + private BukkitScheduler scheduler; private StorageProvider storageProvider; private Slate slate; private MenuFileManager menuFileManager; @@ -578,7 +578,7 @@ public RewardManager getRewardManager() { } @Override - public Scheduler getScheduler() { + public BukkitScheduler getScheduler() { return scheduler; } diff --git a/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/commands/SkillCommands.java b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/commands/SkillCommands.java index 06d3121f2..559b3db2f 100644 --- a/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/commands/SkillCommands.java +++ b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/commands/SkillCommands.java @@ -25,7 +25,7 @@ public SkillCommand(AuraSkills plugin, Skill skill) { protected void openMenu(Player player) { if (skill.isEnabled()) { - new LevelProgressionOpener(plugin).open(player, skill); + plugin.getScheduler().executeAtEntity(player, (t) -> new LevelProgressionOpener(plugin).open(player, skill)); } else { player.sendMessage(plugin.getCommandManager().formatMessage(plugin.getCommandManager().getCommandIssuer(player), MessageType.ERROR, MessageKeys.UNKNOWN_COMMAND)); } diff --git a/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/commands/SkillsRootCommand.java b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/commands/SkillsRootCommand.java index da8ab242b..3037149af 100644 --- a/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/commands/SkillsRootCommand.java +++ b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/commands/SkillsRootCommand.java @@ -311,7 +311,7 @@ public void onClaimItems(Player player) { player.sendMessage(plugin.getPrefix(locale) + plugin.getMsg(CommandMessage.CLAIMITEMS_NO_ITEMS, locale)); return; } - UnclaimedItemsMenu.getInventory(plugin, user).open(player); + plugin.getScheduler().executeAtEntity(player, (t) -> UnclaimedItemsMenu.getInventory(plugin, user).open(player)); } @Subcommand("version") diff --git a/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/commands/StatsCommand.java b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/commands/StatsCommand.java index 11f363705..a513b02a5 100644 --- a/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/commands/StatsCommand.java +++ b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/commands/StatsCommand.java @@ -21,7 +21,7 @@ public StatsCommand(AuraSkills plugin) { @CommandPermission("auraskills.command.stats") @Description("Opens the Stats menu where you can see current stat levels and descriptions.") public void onStats(Player player) { - plugin.getSlate().openMenu(player, "stats"); + plugin.getScheduler().executeAtEntity(player, (t) -> plugin.getSlate().openMenu(player, "stats")); } - + } diff --git a/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/hooks/DecentHologramsHook.java b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/hooks/DecentHologramsHook.java index f489245fb..8606e129b 100644 --- a/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/hooks/DecentHologramsHook.java +++ b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/hooks/DecentHologramsHook.java @@ -27,7 +27,7 @@ public void createHologram(Location location, String text) { } public void deleteHologram(Hologram dh) { - plugin.getScheduler().scheduleSync(dh::delete, 30L * 50L, TimeUnit.MILLISECONDS); + plugin.getScheduler().scheduleAtLocation(dh.getLocation(), dh::delete, 30L * 50L, TimeUnit.MILLISECONDS); } @Override diff --git a/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/hooks/HolographicDisplaysHook.java b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/hooks/HolographicDisplaysHook.java index 7a6d884fa..512e3d881 100644 --- a/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/hooks/HolographicDisplaysHook.java +++ b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/hooks/HolographicDisplaysHook.java @@ -26,7 +26,7 @@ public void createHologram(Location location, String text) { } public void deleteHologram(Hologram hd) { - plugin.getScheduler().scheduleSync(hd::delete, 30L * 50L, TimeUnit.MILLISECONDS); + plugin.getScheduler().scheduleAtLocation(hd.getLocation(), hd::delete, 30L * 50L, TimeUnit.MILLISECONDS); } @Override diff --git a/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/hooks/mythicmobs/MythicMobsHook.java b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/hooks/mythicmobs/MythicMobsHook.java index 5aa4cc993..3d52910d9 100644 --- a/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/hooks/mythicmobs/MythicMobsHook.java +++ b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/hooks/mythicmobs/MythicMobsHook.java @@ -66,6 +66,8 @@ public void onMythicSkillDamage(MythicDamageEvent event) { if (target.hasMetadata("NPC")) return; } + // This is unsafe here since it will read attributes from the player, but since MythicMobs doesn't support + // Folia, we can ignore this. If MythicMobs ever supports Folia, they should fire this event on the proper region DamageResult result = damageHandler.handleDamage( BukkitAdapter.adapt(attacker), BukkitAdapter.adapt(target), getDamageType(attacker), event.getDamageMetadata().getDamageCause(), event.getDamage(), "mythicmobs"); diff --git a/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/level/BukkitLevelManager.java b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/level/BukkitLevelManager.java index dde51cd8b..4327fce29 100644 --- a/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/level/BukkitLevelManager.java +++ b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/level/BukkitLevelManager.java @@ -115,8 +115,10 @@ public void playLevelUpSound(@NotNull User user) { @Override public void reloadModifiers(User user) { Player player = ((BukkitUser) user).getPlayer(); - if (player != null) { - plugin.getModifierManager().reloadPlayer(player); - } + plugin.getScheduler().executeAtEntity(player, t -> { + if (player != null) { + plugin.getModifierManager().reloadPlayer(player); + } + }); } } diff --git a/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/listeners/CriticalHandler.java b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/listeners/CriticalHandler.java index e0cba2396..b2b5c0c15 100644 --- a/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/listeners/CriticalHandler.java +++ b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/listeners/CriticalHandler.java @@ -42,7 +42,7 @@ private DamageModifier getCrit(Player player, User user) { } // Set metadata for holograms to detect player.setMetadata("skillsCritical", new FixedMetadataValue(plugin, true)); - plugin.getScheduler().scheduleSync(() -> player.removeMetadata("skillsCritical", plugin), 50, TimeUnit.MILLISECONDS); + plugin.getScheduler().scheduleAtEntity(player, () -> player.removeMetadata("skillsCritical", plugin), 50, TimeUnit.MILLISECONDS); double value = user.getEffectiveTraitLevel(Traits.CRIT_DAMAGE) / 100; return new DamageModifier(value, DamageModifier.Operation.ADD_COMBINED); diff --git a/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/scheduler/BukkitScheduler.java b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/scheduler/BukkitScheduler.java index c1c309bef..cb4334104 100644 --- a/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/scheduler/BukkitScheduler.java +++ b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/scheduler/BukkitScheduler.java @@ -1,47 +1,82 @@ package dev.aurelium.auraskills.bukkit.scheduler; +import com.tcoded.folialib.FoliaLib; +import com.tcoded.folialib.enums.EntityTaskResult; +import com.tcoded.folialib.wrapper.task.WrappedTask; import dev.aurelium.auraskills.bukkit.AuraSkills; import dev.aurelium.auraskills.common.scheduler.Scheduler; import dev.aurelium.auraskills.common.scheduler.Task; import dev.aurelium.auraskills.common.scheduler.TaskRunnable; -import org.bukkit.scheduler.BukkitTask; +import org.bukkit.Location; +import org.bukkit.entity.Entity; +import java.util.concurrent.CompletableFuture; import java.util.concurrent.TimeUnit; +import java.util.function.Consumer; public class BukkitScheduler extends Scheduler { - private final AuraSkills plugin; + private final FoliaLib foliaLib; public BukkitScheduler(AuraSkills plugin) { super(plugin); - this.plugin = plugin; + this.foliaLib = new FoliaLib(plugin); } @Override public Task executeSync(Runnable runnable) { - BukkitTask task = plugin.getServer().getScheduler().runTask(plugin, runnable); + // Same as runTask. Checked in the original spigot source code. + WrappedTask task = foliaLib.getScheduler().runLater(runnable, 0L); return new BukkitTaskWrapper(task); } @Override public Task scheduleSync(Runnable runnable, long delay, TimeUnit timeUnit) { - BukkitTask task = plugin.getServer().getScheduler().runTaskLater(plugin, runnable, timeUnit.toMillis(delay) / 50); + WrappedTask task = foliaLib.getScheduler().runLater(runnable, delay, timeUnit); return new BukkitTaskWrapper(task); } @Override public Task timerSync(TaskRunnable runnable, long delay, long period, TimeUnit timeUnit) { - BukkitTask bukkitTask = plugin.getServer().getScheduler().runTaskTimer(plugin, runnable, timeUnit.toMillis(delay) / 50, timeUnit.toMillis(period) / 50); - Task task = new BukkitTaskWrapper(bukkitTask); + WrappedTask bukkitTask = foliaLib.getScheduler().runTimer(runnable, delay, period, timeUnit); + Task task = new BukkitTaskWrapper(bukkitTask); runnable.injectTask(task); return task; } @Override public Task timerAsync(TaskRunnable runnable, long delay, long period, TimeUnit timeUnit) { - BukkitTask bukkitTask = plugin.getServer().getScheduler().runTaskTimerAsynchronously(plugin, runnable, timeUnit.toMillis(delay) / 50, timeUnit.toMillis(period) / 50); + WrappedTask bukkitTask = foliaLib.getScheduler().runTimerAsync(runnable, delay, period, timeUnit); Task task = new BukkitTaskWrapper(bukkitTask); runnable.injectTask(task); return task; } + + public CompletableFuture executeAtLocation(Location location, Consumer consumer) { + return foliaLib.getScheduler().runAtLocation(location, consumer); + } + + public Task scheduleAtLocation(Location location, Runnable runnable, long delay, TimeUnit timeUnit) { + WrappedTask task = foliaLib.getScheduler().runAtLocationLater(location, runnable, delay, timeUnit); + return new BukkitTaskWrapper(task); + } + + public Task timerAtLocation(Location location, Runnable runnable, long delay, long period, TimeUnit timeUnit) { + WrappedTask task = foliaLib.getScheduler().runAtLocationTimer(location, runnable, delay, period, timeUnit); + return new BukkitTaskWrapper(task); + } + + public CompletableFuture executeAtEntity(Entity entity, Consumer consumer) { + return foliaLib.getScheduler().runAtEntity(entity, consumer); + } + + public Task scheduleAtEntity(Entity entity, Runnable runnable, long delay, TimeUnit timeUnit) { + WrappedTask task = foliaLib.getScheduler().runAtEntityLater(entity, runnable, delay, timeUnit); + return new BukkitTaskWrapper(task); + } + + public Task timerAtEntity(Entity entity, Runnable runnable, long delay, long period, TimeUnit timeUnit) { + WrappedTask task = foliaLib.getScheduler().runAtEntityTimer(entity, runnable, delay, period, timeUnit); + return new BukkitTaskWrapper(task); + } } diff --git a/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/scheduler/BukkitTaskWrapper.java b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/scheduler/BukkitTaskWrapper.java index fc4523f4d..e79e37c0f 100644 --- a/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/scheduler/BukkitTaskWrapper.java +++ b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/scheduler/BukkitTaskWrapper.java @@ -1,5 +1,6 @@ package dev.aurelium.auraskills.bukkit.scheduler; +import com.tcoded.folialib.wrapper.task.WrappedTask; import dev.aurelium.auraskills.common.scheduler.Task; import dev.aurelium.auraskills.common.scheduler.TaskStatus; import org.bukkit.Bukkit; @@ -7,9 +8,9 @@ public class BukkitTaskWrapper implements Task { - private final BukkitTask bukkitTask; + private final WrappedTask bukkitTask; - public BukkitTaskWrapper(BukkitTask bukkitTask) { + public BukkitTaskWrapper(WrappedTask bukkitTask) { this.bukkitTask = bukkitTask; } @@ -24,6 +25,6 @@ public TaskStatus getStatus() { @Override public void cancel() { - Bukkit.getScheduler().cancelTask(bukkitTask.getTaskId()); + bukkitTask.cancel(); } } diff --git a/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/skills/agility/AgilityAbilities.java b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/skills/agility/AgilityAbilities.java index 034dfea5e..3e7aecc1d 100644 --- a/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/skills/agility/AgilityAbilities.java +++ b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/skills/agility/AgilityAbilities.java @@ -189,7 +189,9 @@ public void startFleetingRemoveTimer() { @Override public void run() { for (Player player : Bukkit.getOnlinePlayers()) { - removeFleeting(player); + plugin.getScheduler().executeAtEntity(player, (t) -> { + removeFleeting(player); + }); } } }, 5, 5, TimeUnit.SECONDS); diff --git a/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/skills/alchemy/AlchemyAbilities.java b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/skills/alchemy/AlchemyAbilities.java index d890be055..4e3299713 100644 --- a/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/skills/alchemy/AlchemyAbilities.java +++ b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/skills/alchemy/AlchemyAbilities.java @@ -73,13 +73,13 @@ public void alchemist(BrewEvent event) { if (failsChecks(player, ability)) return; User user = plugin.getUser(player); - updateBrewingStand(inventory, user, user.getLocale()); + updateBrewingStand(event, inventory, user, user.getLocale()); } - private void updateBrewingStand(BrewerInventory inventory, User user, Locale locale) { + private void updateBrewingStand(BrewEvent event, BrewerInventory inventory, User user, Locale locale) { var ability = Abilities.ALCHEMIST; - plugin.getScheduler().scheduleSync(() -> { + plugin.getScheduler().scheduleAtLocation(event.getBlock().getLocation(), () -> { ItemStack[] contents = inventory.getContents(); double multiplier = 1 + (getValue(ability, user) / 100); for (int i = 0; i < contents.length; i++) { diff --git a/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/skills/archery/ArcheryAbilities.java b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/skills/archery/ArcheryAbilities.java index 95a34a921..2b7aee98a 100644 --- a/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/skills/archery/ArcheryAbilities.java +++ b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/skills/archery/ArcheryAbilities.java @@ -138,7 +138,7 @@ public void stun(Player player, User user, LivingEntity entity) { } private void scheduleStunRemoval(LivingEntity entity) { - plugin.getScheduler().scheduleSync(() -> { + plugin.getScheduler().scheduleAtEntity(entity, () -> { AttributeInstance newSpeed = entity.getAttribute(AttributeCompat.MOVEMENT_SPEED); if (newSpeed == null) return; for (AttributeModifier attributeModifier : newSpeed.getModifiers()) { @@ -234,7 +234,7 @@ public void retrieval(ProjectileHitEvent event) { if (failsChecks(player, ability)) return; ItemStack item = getArrowItem(arrow); - plugin.getScheduler().scheduleSync(() -> { + plugin.getScheduler().scheduleAtEntity(arrow, () -> { if (!arrow.isValid()) return; // Ignore if the arrow has de-spawned or was picked up if (!arrow.getWorld().equals(player.getWorld())) return; @@ -246,14 +246,19 @@ public void retrieval(ProjectileHitEvent event) { item.setAmount(1); // Abort if the player doesn't have enough inventory space - if (!player.getInventory().addItem(item).isEmpty()) { - return; - } + plugin.getScheduler().executeAtEntity(player, (t) -> { + if (!player.getInventory().addItem(item).isEmpty()) { + return; + } + + plugin.getScheduler().executeAtEntity(arrow, (t2) -> { + arrow.getWorld().spawnParticle(CompatUtil.witchParticle(), arrow.getLocation(), 5, 0, 0, 0); + player.playSound(player.getLocation(), Sound.ENTITY_ITEM_PICKUP, 0.4f, 1.9f); - arrow.getWorld().spawnParticle(CompatUtil.witchParticle(), arrow.getLocation(), 5, 0, 0, 0); - player.playSound(player.getLocation(), Sound.ENTITY_ITEM_PICKUP, 0.4f, 1.9f); + arrow.remove(); + }); + }); - arrow.remove(); }, Math.round(ability.optionDouble("delay_sec", 3) * 1000), TimeUnit.MILLISECONDS); } @@ -308,7 +313,8 @@ private void setLegacyTippedArrow(Arrow arrow, PotionMeta meta) { Method setBasePotionData = PotionMeta.class.getDeclaredMethod("setBasePotionData", potionDataClass); setBasePotionData.invoke(meta, potionData); - } catch (InvocationTargetException | IllegalAccessException | NoSuchMethodException | ClassNotFoundException e) { + } catch (InvocationTargetException | IllegalAccessException | NoSuchMethodException | + ClassNotFoundException e) { throw new RuntimeException(e); } } diff --git a/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/skills/defense/DefenseAbilities.java b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/skills/defense/DefenseAbilities.java index 28d3c760b..bb9ff7269 100644 --- a/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/skills/defense/DefenseAbilities.java +++ b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/skills/defense/DefenseAbilities.java @@ -124,7 +124,7 @@ public void noDebuffFire(User user, Player player, LivingEntity entity) { if (item.getEnchantmentLevel(Enchantment.FIRE_ASPECT) > 0) { double chance = getValue(ability, user) / 100; if (rand.nextDouble() < chance) { - plugin.getScheduler().scheduleSync(() -> player.setFireTicks(0), 50, TimeUnit.MILLISECONDS); + plugin.getScheduler().scheduleAtEntity(player, () -> player.setFireTicks(0), 50, TimeUnit.MILLISECONDS); } } } diff --git a/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/skills/farming/FarmingAbilities.java b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/skills/farming/FarmingAbilities.java index 6f0d1ddbf..e25d58b08 100644 --- a/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/skills/farming/FarmingAbilities.java +++ b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/skills/farming/FarmingAbilities.java @@ -120,7 +120,7 @@ private void handleGrowthAura(Player player, Block block, BlockState state) { if (state.getBlockData() instanceof Ageable ageable) { // Add growth stages with 1 tick delay - plugin.getScheduler().scheduleSync(() -> { + plugin.getScheduler().scheduleAtLocation(block.getLocation(), () -> { if (block.getType() != state.getType()) return; ageable.setAge(Math.min(ageable.getAge() + extraStages, ageable.getMaximumAge())); diff --git a/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/skills/farming/Replenish.java b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/skills/farming/Replenish.java index 4e9984644..48ddc78b7 100644 --- a/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/skills/farming/Replenish.java +++ b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/skills/farming/Replenish.java @@ -75,7 +75,7 @@ private boolean isFullyGrown(Block block) { private void replantCrop(Block block) { Material material = block.getType(); - plugin.getScheduler().scheduleSync(() -> { + plugin.getScheduler().scheduleAtLocation(block.getLocation(), () -> { if (material != Material.NETHER_WART) { if (block.getRelative(BlockFace.DOWN).getType() == Material.FARMLAND) { block.setType(material); diff --git a/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/skills/fighting/FightingAbilities.java b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/skills/fighting/FightingAbilities.java index ef274bf84..e41272a9b 100644 --- a/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/skills/fighting/FightingAbilities.java +++ b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/skills/fighting/FightingAbilities.java @@ -95,7 +95,7 @@ private DamageModifier firstStrike(User user, Player player) { int id = abilityData.getInt("counter"); // Schedules metadata removal long cooldown = ability.optionInt("cooldown_ticks", 6000); - plugin.getScheduler().scheduleSync(() -> { + plugin.getScheduler().scheduleAtEntity(player, () -> { if (user.getAbilityData(ability).containsKey("counter")) { if (user.getAbilityData(ability).getInt("counter") == id) { player.removeMetadata("AureliumSkills-FirstStrike", plugin); @@ -308,7 +308,7 @@ public DamageModifier handleParry(DamageEvent event, Player player, User user) { Vector velBefore = player.getVelocity(); // Disable knockback - plugin.getScheduler().scheduleSync(() -> player.setVelocity(velBefore), + plugin.getScheduler().scheduleAtEntity(player, () -> player.setVelocity(velBefore), 50, TimeUnit.MILLISECONDS); return new DamageModifier((1 - value / 100) - 1, DamageModifier.Operation.MULTIPLY); diff --git a/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/skills/foraging/Treecapitator.java b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/skills/foraging/Treecapitator.java index 7def9afed..5a28adf27 100644 --- a/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/skills/foraging/Treecapitator.java +++ b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/skills/foraging/Treecapitator.java @@ -115,7 +115,7 @@ private void breakBlock(User user, Block block, TreecapitatorTree tree) { return; } // Break the next blocks - plugin.getScheduler().scheduleSync(() -> breakBlock(user, adjacentBlock, tree), 50, TimeUnit.MILLISECONDS); + plugin.getScheduler().scheduleAtLocation(adjacentBlock.getLocation(), () -> breakBlock(user, adjacentBlock, tree), 50, TimeUnit.MILLISECONDS); } } diff --git a/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/source/BlockLeveler.java b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/source/BlockLeveler.java index 1e58216ad..185814294 100644 --- a/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/source/BlockLeveler.java +++ b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/source/BlockLeveler.java @@ -105,7 +105,7 @@ public void onInteract(PlayerInteractEvent event) { Material materialBefore = block.getType(); if (source.getAfterStates() != null) { - plugin.getScheduler().scheduleSync(() -> { + plugin.getScheduler().scheduleAtLocation(block.getLocation(), () -> { // Checks that the block after one tick is the same material and matches the after_state/after_states if (materialBefore == block.getType() && matchesStates(block, source.getAfterStates())) { plugin.getLevelManager().addXp(user, skill, source, source.getXp() * multiplier); diff --git a/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/source/BrewingLeveler.java b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/source/BrewingLeveler.java index a2ebd9d76..6398a40b5 100644 --- a/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/source/BrewingLeveler.java +++ b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/source/BrewingLeveler.java @@ -138,7 +138,7 @@ private void checkBrewedSlots(BrewEvent event) { if (ingredient == null) return; ItemStack clonedIngredient = ingredient.clone(); ItemStack[] beforeItems = Arrays.copyOf(before.getContents(), 3); // Items in result slots before - plugin.getScheduler().scheduleSync(() -> { + plugin.getScheduler().scheduleAtLocation(event.getBlock().getLocation(), () -> { BlockState blockState = event.getBlock().getState(); if (blockState instanceof BrewingStand brewingStand) { BrewerInventory after = brewingStand.getInventory(); diff --git a/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/trait/HealthRegenTraits.java b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/trait/HealthRegenTraits.java index 677f4577d..3c4cb8d49 100644 --- a/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/trait/HealthRegenTraits.java +++ b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/trait/HealthRegenTraits.java @@ -86,7 +86,7 @@ public void run() { } } }; - plugin.getScheduler().timerSync(task, 0, Traits.HUNGER_REGEN.optionInt("delay", 60) * 50L, TimeUnit.MILLISECONDS); + plugin.getScheduler().timerAsync(task, 0, Traits.HUNGER_REGEN.optionInt("delay", 60) * 50L, TimeUnit.MILLISECONDS); } private void startSaturationRegen() { @@ -100,40 +100,43 @@ public void run() { } } }; - plugin.getScheduler().timerSync(task, 0, Traits.SATURATION_REGEN.optionInt("delay", 20) * 50L, TimeUnit.MILLISECONDS); + plugin.getScheduler().timerAsync(task, 0, Traits.SATURATION_REGEN.optionInt("delay", 20) * 50L, TimeUnit.MILLISECONDS); } private void handleCustomRegen(Player player, Trait trait, Function regenCondition, CustomRegenEvent.Reason reason) { - User user = plugin.getUser(player); + plugin.getScheduler().executeAtEntity(player, (t) -> { + User user = plugin.getUser(player); - if (plugin.getWorldManager().isInDisabledWorld(player.getLocation())) return; + if (plugin.getWorldManager().isInDisabledWorld(player.getLocation())) return; - if (player.isDead()) return; + if (player.isDead()) return; AttributeInstance attribute = player.getAttribute(AttributeCompat.MAX_HEALTH); if (attribute == null) return; - if (!(player.getHealth() < attribute.getValue())) return; + if (!(player.getHealth() < attribute.getValue())) return; - if (regenCondition.apply(player)) { - double amountGained = Math.min(trait.optionDouble("base") + user.getBonusTraitLevel(trait) - , attribute.getValue() - player.getHealth()); + if (regenCondition.apply(player)) { + double amountGained = Math.min(trait.optionDouble("base") + user.getBonusTraitLevel(trait) + , attribute.getValue() - player.getHealth()); - final double gainThreshold = 0.001; - if (amountGained < gainThreshold) { - return; - } + final double gainThreshold = 0.001; + if (amountGained < gainThreshold) { + return; + } - CustomRegenEvent event = new CustomRegenEvent(player, user.toApi(), amountGained, reason); - Bukkit.getPluginManager().callEvent(event); + CustomRegenEvent event = new CustomRegenEvent(player, user.toApi(), amountGained, reason); + Bukkit.getPluginManager().callEvent(event); - if (!event.isCancelled()) { - player.setHealth(player.getHealth() + amountGained); - if (player.getFoodLevel() - 1 >= 0) { - player.setFoodLevel(player.getFoodLevel() - 1); + if (!event.isCancelled()) { + player.setHealth(player.getHealth() + amountGained); + if (player.getFoodLevel() - 1 >= 0) { + player.setFoodLevel(player.getFoodLevel() - 1); + } } } - } + + }); } } diff --git a/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/trait/HpTrait.java b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/trait/HpTrait.java index df4442bc9..309f6229d 100644 --- a/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/trait/HpTrait.java +++ b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/trait/HpTrait.java @@ -72,9 +72,10 @@ public void onJoin(PlayerJoinEvent event) { @Override public void reload(Player player, Trait trait) { - setHealth(player, plugin.getUser(player)); - - plugin.getAbilityManager().getAbilityImpl(AgilityAbilities.class).removeFleeting(player); + plugin.getScheduler().executeAtEntity(player, (t) -> { + setHealth(player, plugin.getUser(player)); + plugin.getAbilityManager().getAbilityImpl(AgilityAbilities.class).removeFleeting(player); + }); } @Override @@ -92,7 +93,7 @@ public void worldChange(PlayerChangedWorldEvent event) { } User user = plugin.getUser(player); if (Traits.HP.optionInt("update_delay") > 0) { - plugin.getScheduler().scheduleSync(() -> setWorldChange(event, player, user), + plugin.getScheduler().scheduleAtEntity(player, () -> setWorldChange(event, player, user), Traits.HP.optionInt("update_delay") * 50L, TimeUnit.MILLISECONDS); } else { setWorldChange(event, player, user); diff --git a/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/trait/LuckTrait.java b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/trait/LuckTrait.java index d82dc8841..66d34bd01 100644 --- a/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/trait/LuckTrait.java +++ b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/trait/LuckTrait.java @@ -45,12 +45,12 @@ public double getBaseLevel(Player player, Trait trait) { @EventHandler public void onJoin(UserLoadEvent event) { - setLuck(event.getPlayer()); + plugin.getScheduler().executeAtEntity(event.getPlayer(), (t) -> setLuck(event.getPlayer())); } @Override public void reload(Player player, Trait trait) { - setLuck(player); + plugin.getScheduler().executeAtEntity(player, (t) -> setLuck(player)); } @EventHandler @@ -112,7 +112,8 @@ private boolean isLuckTraitModifier(AttributeModifier modifier) { if (namespace.equals("minecraft") && modifier.getAmount() == 0 && modifier.getOperation().equals(Operation.ADD_NUMBER)) { return true; } - } catch (IllegalArgumentException ignored) { } + } catch (IllegalArgumentException ignored) { + } } } return false; diff --git a/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/trait/MovementSpeedTrait.java b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/trait/MovementSpeedTrait.java index 720118578..1c80492d7 100644 --- a/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/trait/MovementSpeedTrait.java +++ b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/trait/MovementSpeedTrait.java @@ -33,21 +33,23 @@ public double getBaseLevel(Player player, Trait trait) { @Override protected void reload(Player player, Trait trait) { - double WALK_SPEED_RATIO = 500; - double value = getValue(player, trait, WALK_SPEED_RATIO); + plugin.getScheduler().executeAtEntity(player, (t) -> { + double WALK_SPEED_RATIO = 500; + double value = getValue(player, trait, WALK_SPEED_RATIO); - if (!trait.isEnabled()) return; - if (plugin.getWorldManager().isInDisabledWorld(player.getLocation())) { - player.setWalkSpeed(0.2f); - return; - } - double max = trait.optionDouble("max") / WALK_SPEED_RATIO; - if (0.2 + value > max) { - player.setWalkSpeed((float) (max)); - return; - } + if (!trait.isEnabled()) return; + if (plugin.getWorldManager().isInDisabledWorld(player.getLocation())) { + player.setWalkSpeed(0.2f); + return; + } + double max = trait.optionDouble("max") / WALK_SPEED_RATIO; + if (0.2 + value > max) { + player.setWalkSpeed((float) (max)); + return; + } - player.setWalkSpeed(Math.min((float) (0.2 + value), 1f)); + player.setWalkSpeed(Math.min((float) (0.2 + value), 1f)); + }); } @EventHandler diff --git a/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/ui/BossBarManager.java b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/ui/BossBarManager.java index d85f23318..f838cb94b 100644 --- a/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/ui/BossBarManager.java +++ b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/ui/BossBarManager.java @@ -204,7 +204,7 @@ private BossBar handleNewBossBar(Player player, Skill skill, float progressOld, if (!ANIMATE_PROGRESS) { // If the config option is disabled, immediately show new progress bossBar.progress(progressNew); } else { // Update the progress later to display its animation from progressOld to progressNew - plugin.getScheduler().scheduleSync(() -> bossBar.progress(progressNew), 2 * 50, TimeUnit.MILLISECONDS); + plugin.getScheduler().scheduleAtEntity(player, () -> bossBar.progress(progressNew), 2 * 50, TimeUnit.MILLISECONDS); } plugin.getAudiences().player(player).showBossBar(bossBar); @@ -223,7 +223,7 @@ private void handleExistingBossBar(BossBar bossBar, Player player, Skill skill, if (!ANIMATE_PROGRESS) { // Update boss bar progress immediately bossBar.progress(progress); } else { // Update progress later, so the player sees the animation from previous progress (from reused boss bar) to new - plugin.getScheduler().scheduleSync(() -> bossBar.progress(progress), 2 * 50, TimeUnit.MILLISECONDS); + plugin.getScheduler().scheduleAtEntity(player, () -> bossBar.progress(progress), 2 * 50, TimeUnit.MILLISECONDS); } bossBar.name(name); // Update the boss bar to the new text value bossBar.color(getColor(skill)); diff --git a/bukkit/src/main/resources/plugin.yml b/bukkit/src/main/resources/plugin.yml index c1d3281b1..32fe6d116 100644 --- a/bukkit/src/main/resources/plugin.yml +++ b/bukkit/src/main/resources/plugin.yml @@ -8,6 +8,8 @@ softdepend: [WorldGuard, PlaceholderAPI, HolographicDisplays, DecentHolograms, V api-version: '1.13' prefix: AuraSkills +folia-supported: true + permissions: auraskills.*: description: Permission to use all commands from AuraSkills From 1f12bfbd9f33dae81877ce29934f729d1fbf3e3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erik=20Szab=C3=B3?= Date: Thu, 24 Oct 2024 14:03:16 +0200 Subject: [PATCH 2/8] Redirect console/player command executions to the proper thread --- .../java/dev/aurelium/auraskills/bukkit/AuraSkills.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/AuraSkills.java b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/AuraSkills.java index ff6c5beb7..65fa10f3b 100644 --- a/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/AuraSkills.java +++ b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/AuraSkills.java @@ -647,14 +647,16 @@ public String getPrefix(Locale locale) { @Override public void runConsoleCommand(String command) { - getServer().dispatchCommand(getServer().getConsoleSender(), command); + // Console commands need to be run on the global region scheduler + scheduler.executeSync(() -> getServer().dispatchCommand(getServer().getConsoleSender(), command)); } @Override public void runPlayerCommand(User user, String command) { Player player = ((BukkitUser) user).getPlayer(); if (player != null) { - getServer().dispatchCommand(player, command); + // Use performCommand and redirect it to the proper thread + scheduler.executeAtEntity(player, (t) -> player.performCommand(command)); } } From 5a6e27b843cbf613460051343e59d80e1e1fa0e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erik=20Szab=C3=B3?= Date: Thu, 24 Oct 2024 14:09:23 +0200 Subject: [PATCH 3/8] Redirect item adding to the proper player threads --- .../bukkit/commands/ItemCommand.java | 47 ++++++++++--------- .../bukkit/item/BukkitItemRegistry.java | 20 ++++---- .../bukkit/item/UnclaimedItemsMenu.java | 1 + 3 files changed, 36 insertions(+), 32 deletions(-) diff --git a/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/commands/ItemCommand.java b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/commands/ItemCommand.java index e2ab38566..ad4c8c82a 100644 --- a/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/commands/ItemCommand.java +++ b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/commands/ItemCommand.java @@ -247,8 +247,7 @@ public void onItemRequirementRemove(@Flags("itemheld") Player player, Skill skil player.getInventory().setItemInMainHand(item); player.sendMessage(plugin.getPrefix(locale) + TextUtil.replace(plugin.getMsg(CommandMessage.ITEM_REQUIREMENT_REMOVE_REMOVED, locale), "{skill}", skill.getDisplayName(locale))); - } - else { + } else { player.sendMessage(plugin.getPrefix(locale) + TextUtil.replace(plugin.getMsg(CommandMessage.ITEM_REQUIREMENT_REMOVE_DOES_NOT_EXIST, locale), "{skill}", skill.getDisplayName(locale))); } @@ -325,31 +324,33 @@ public void onItemGive(CommandSender sender, @Flags("other") Player player, Stri if (amount != -1) { item.setAmount(amount); } - ItemStack leftoverItem = ItemUtils.addItemToInventory(player, item); + plugin.getScheduler().executeAtEntity(player, (t) -> { + ItemStack leftoverItem = ItemUtils.addItemToInventory(player, item); - String senderMsg = TextUtil.replace(plugin.getMsg(CommandMessage.ITEM_GIVE_SENDER, locale), - "{amount}", String.valueOf(item.getAmount()), "{key}", key, "{player}", player.getName()); - if (!senderMsg.isEmpty()) { - sender.sendMessage(plugin.getPrefix(locale) + senderMsg); - } + String senderMsg = TextUtil.replace(plugin.getMsg(CommandMessage.ITEM_GIVE_SENDER, locale), + "{amount}", String.valueOf(item.getAmount()), "{key}", key, "{player}", player.getName()); + if (!senderMsg.isEmpty()) { + sender.sendMessage(plugin.getPrefix(locale) + senderMsg); + } - if (!sender.equals(player)) { - String message = TextUtil.replace(plugin.getMsg(CommandMessage.ITEM_GIVE_RECEIVER, locale), - "{amount}", String.valueOf(item.getAmount()), "{key}", key); - if (!message.isEmpty()) { - player.sendMessage(plugin.getPrefix(locale) + message); + if (!sender.equals(player)) { + String message = TextUtil.replace(plugin.getMsg(CommandMessage.ITEM_GIVE_RECEIVER, locale), + "{amount}", String.valueOf(item.getAmount()), "{key}", key); + if (!message.isEmpty()) { + player.sendMessage(plugin.getPrefix(locale) + message); + } } - } - // Add to unclaimed items if leftover - if (leftoverItem != null) { - User user = plugin.getUser(player); - user.getUnclaimedItems().add(new KeyIntPair(key, leftoverItem.getAmount())); - - String message = plugin.getMsg(LevelerMessage.UNCLAIMED_ITEM, locale); - if (!message.isEmpty()) { - player.sendMessage(plugin.getPrefix(locale) + message); + // Add to unclaimed items if leftover + if (leftoverItem != null) { + User user = plugin.getUser(player); + user.getUnclaimedItems().add(new KeyIntPair(key, leftoverItem.getAmount())); + + String message = plugin.getMsg(LevelerMessage.UNCLAIMED_ITEM, locale); + if (!message.isEmpty()) { + player.sendMessage(plugin.getPrefix(locale) + message); + } } - } + }); } else { sender.sendMessage(plugin.getPrefix(locale) + TextUtil.replace(plugin.getMsg(CommandMessage.ITEM_UNREGISTER_NOT_REGISTERED, locale), "{key}", key)); } diff --git a/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/item/BukkitItemRegistry.java b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/item/BukkitItemRegistry.java index 4681257f7..67490af65 100644 --- a/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/item/BukkitItemRegistry.java +++ b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/item/BukkitItemRegistry.java @@ -83,15 +83,17 @@ public void giveItem(User user, NamespacedId key, int amount) { return; } - ItemStack leftoverItem = ItemUtils.addItemToInventory(player, item); // Attempt item give - // Handle items that could not fit in the inventory - if (leftoverItem != null) { - // Add unclaimed item key and amount to player data - user.getUnclaimedItems().add(new KeyIntPair(key.toString(), leftoverItem.getAmount())); - // Notify player - plugin.getServer().getScheduler().runTaskLater(plugin, () -> - player.sendMessage(plugin.getPrefix(user.getLocale()) + plugin.getMsg(LevelerMessage.UNCLAIMED_ITEM, user.getLocale())), 1); - } + plugin.getScheduler().executeAtEntity(player, (t) -> { + ItemStack leftoverItem = ItemUtils.addItemToInventory(player, item); // Attempt item give + // Handle items that could not fit in the inventory + if (leftoverItem != null) { + // Add unclaimed item key and amount to player data + user.getUnclaimedItems().add(new KeyIntPair(key.toString(), leftoverItem.getAmount())); + // Notify player + plugin.getScheduler().executeSync(() -> + player.sendMessage(plugin.getPrefix(user.getLocale()) + plugin.getMsg(LevelerMessage.UNCLAIMED_ITEM, user.getLocale()))); + } + }); } @Override diff --git a/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/item/UnclaimedItemsMenu.java b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/item/UnclaimedItemsMenu.java index 7f208efc5..9578bf930 100644 --- a/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/item/UnclaimedItemsMenu.java +++ b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/item/UnclaimedItemsMenu.java @@ -49,6 +49,7 @@ public void init(Player player, InventoryContents contents) { item.setAmount(amount); contents.set(row, column, ClickableItem.from(getDisplayItem(item), data -> { // Give item on click + // This should be running already on the thread that owns the player entity ItemStack leftoverItem = ItemUtils.addItemToInventory(player, item); if (leftoverItem == null) { // All items were added user.getUnclaimedItems().remove(keyIntPair); From 49fa3f5a297920a36ba707e6490703494824a3f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erik=20Szab=C3=B3?= Date: Thu, 24 Oct 2024 14:16:10 +0200 Subject: [PATCH 4/8] Replaced some collections in User to their concurrent variants --- .../aurelium/auraskills/common/user/User.java | 25 +++++++++++-------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/common/src/main/java/dev/aurelium/auraskills/common/user/User.java b/common/src/main/java/dev/aurelium/auraskills/common/user/User.java index 571f3b876..af3b2e806 100644 --- a/common/src/main/java/dev/aurelium/auraskills/common/user/User.java +++ b/common/src/main/java/dev/aurelium/auraskills/common/user/User.java @@ -1,5 +1,7 @@ package dev.aurelium.auraskills.common.user; +import com.google.common.collect.Maps; +import com.google.common.collect.Sets; import dev.aurelium.auraskills.api.ability.Ability; import dev.aurelium.auraskills.api.ability.AbstractAbility; import dev.aurelium.auraskills.api.mana.ManaAbility; @@ -67,22 +69,23 @@ public abstract class User { public User(UUID uuid, AuraSkillsPlugin plugin) { this.plugin = plugin; this.uuid = uuid; - this.skillLevels = new ConcurrentHashMap<>(); - this.skillXp = new ConcurrentHashMap<>(); - this.statLevels = new ConcurrentHashMap<>(); - this.statModifiers = new ConcurrentHashMap<>(); - this.traitModifiers = new ConcurrentHashMap<>(); - this.abilityData = new ConcurrentHashMap<>(); - this.manaAbilityData = new ConcurrentHashMap<>(); - this.metadata = new ConcurrentHashMap<>(); - this.actionBarSettings = new ConcurrentHashMap<>(); + this.skillLevels = Maps.newConcurrentMap(); + this.skillXp = Maps.newConcurrentMap(); + this.statLevels = Maps.newConcurrentMap(); + this.statModifiers = Maps.newConcurrentMap(); + this.traitModifiers = Maps.newConcurrentMap(); + this.abilityData = Maps.newConcurrentMap(); + this.manaAbilityData = Maps.newConcurrentMap(); + this.metadata = Maps.newConcurrentMap(); + this.actionBarSettings = Maps.newConcurrentMap(); this.unclaimedItems = new LinkedList<>(); this.saving = false; this.shouldSave = true; this.mana = Traits.MAX_MANA.isEnabled() ? Traits.MAX_MANA.optionDouble("base") : 0.0; - this.multipliers = new HashMap<>(); - this.jobs = new HashSet<>(); + this.multipliers = Maps.newConcurrentMap(); + this.jobs = Sets.newConcurrentHashSet(); this.jobsBatchData = new JobsBatchData(); + // This should be fine as a regular list this.sessionAntiAfkLogs = new ArrayList<>(); this.lastJobSelectTime = 0; } From d859717dcadf5237465762f4fa822927aa2ae4fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erik=20Szab=C3=B3?= Date: Thu, 24 Oct 2024 15:18:21 +0200 Subject: [PATCH 5/8] Remove unnecessary scheduler calls (slate will handle it) --- .../dev/aurelium/auraskills/bukkit/commands/SkillCommands.java | 2 +- .../dev/aurelium/auraskills/bukkit/commands/StatsCommand.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/commands/SkillCommands.java b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/commands/SkillCommands.java index 559b3db2f..06d3121f2 100644 --- a/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/commands/SkillCommands.java +++ b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/commands/SkillCommands.java @@ -25,7 +25,7 @@ public SkillCommand(AuraSkills plugin, Skill skill) { protected void openMenu(Player player) { if (skill.isEnabled()) { - plugin.getScheduler().executeAtEntity(player, (t) -> new LevelProgressionOpener(plugin).open(player, skill)); + new LevelProgressionOpener(plugin).open(player, skill); } else { player.sendMessage(plugin.getCommandManager().formatMessage(plugin.getCommandManager().getCommandIssuer(player), MessageType.ERROR, MessageKeys.UNKNOWN_COMMAND)); } diff --git a/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/commands/StatsCommand.java b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/commands/StatsCommand.java index a513b02a5..5fbe9b04e 100644 --- a/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/commands/StatsCommand.java +++ b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/commands/StatsCommand.java @@ -21,7 +21,7 @@ public StatsCommand(AuraSkills plugin) { @CommandPermission("auraskills.command.stats") @Description("Opens the Stats menu where you can see current stat levels and descriptions.") public void onStats(Player player) { - plugin.getScheduler().executeAtEntity(player, (t) -> plugin.getSlate().openMenu(player, "stats")); + plugin.getSlate().openMenu(player, "stats"); } } From cd4d731a492ec41a60a2d8364714341bdc0aa5cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erik=20Szab=C3=B3?= Date: Thu, 24 Oct 2024 15:38:05 +0200 Subject: [PATCH 6/8] Remove all new BukkitRunnable calls and actually fix some checks in region listener (support side/below) --- .../bukkit/commands/ProfileCommand.java | 19 ++---- .../bukkit/commands/SkillsRootCommand.java | 18 +++--- .../bukkit/region/RegionBlockListener.java | 61 +++++++++---------- .../skills/healing/HealingAbilities.java | 15 +++-- 4 files changed, 47 insertions(+), 66 deletions(-) diff --git a/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/commands/ProfileCommand.java b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/commands/ProfileCommand.java index d6a24143e..e2053c9a7 100644 --- a/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/commands/ProfileCommand.java +++ b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/commands/ProfileCommand.java @@ -11,16 +11,15 @@ import dev.aurelium.auraskills.api.skill.Skill; import dev.aurelium.auraskills.api.stat.Stat; import dev.aurelium.auraskills.api.stat.StatModifier; +import dev.aurelium.auraskills.api.util.NumberUtil; import dev.aurelium.auraskills.bukkit.AuraSkills; import dev.aurelium.auraskills.common.message.type.CommandMessage; import dev.aurelium.auraskills.common.user.User; import dev.aurelium.auraskills.common.user.UserState; -import dev.aurelium.auraskills.api.util.NumberUtil; import dev.aurelium.auraskills.common.util.text.TextUtil; import org.bukkit.Bukkit; import org.bukkit.OfflinePlayer; import org.bukkit.command.CommandSender; -import org.bukkit.scheduler.BukkitRunnable; import java.util.*; @@ -53,12 +52,8 @@ public void onSkills(CommandSender sender, String player) { plugin.getScheduler().executeAsync(() -> { try { UserState userState = plugin.getStorageProvider().loadState(uuid); - new BukkitRunnable() { - @Override - public void run() { - sendSkillsMessage(sender, player, uuid, userState.skillLevels(), userState.skillXp()); - } - }.runTask(plugin); + plugin.getScheduler().executeSync(() -> + sendSkillsMessage(sender, player, uuid, userState.skillLevels(), userState.skillXp())); } catch (Exception ignored) { sender.sendMessage(manager.formatMessage(manager.getCommandIssuer(sender), MessageType.ERROR, MinecraftMessageKeys.NO_PLAYER_FOUND, "{search}", player)); } @@ -85,12 +80,8 @@ public void onStats(CommandSender sender, String player) { plugin.getScheduler().executeAsync(() -> { try { UserState userState = plugin.getStorageProvider().loadState(uuid); - new BukkitRunnable() { - @Override - public void run() { - sendStatsMessage(sender, player, uuid, userState.skillLevels(), userState.statModifiers()); - } - }.runTask(plugin); + plugin.getScheduler().executeSync(() -> + sendStatsMessage(sender, player, uuid, userState.skillLevels(), userState.statModifiers())); } catch (Exception ignored) { sender.sendMessage(manager.formatMessage(manager.getCommandIssuer(sender), MessageType.ERROR, MinecraftMessageKeys.NO_PLAYER_FOUND, "{search}", player)); } diff --git a/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/commands/SkillsRootCommand.java b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/commands/SkillsRootCommand.java index 3037149af..e4d9717b6 100644 --- a/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/commands/SkillsRootCommand.java +++ b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/commands/SkillsRootCommand.java @@ -26,7 +26,6 @@ import org.bukkit.command.ConsoleCommandSender; import org.bukkit.command.RemoteConsoleCommandSender; import org.bukkit.entity.Player; -import org.bukkit.scheduler.BukkitRunnable; import java.util.*; import java.util.concurrent.CompletableFuture; @@ -393,17 +392,14 @@ private CompletableFuture getPlayerDataState(OfflinePlayer player) { future.complete(null); } } else { - new BukkitRunnable() { - @Override - public void run() { - try { - future.complete(plugin.getStorageProvider().loadState(player.getUniqueId())); - } catch (Exception e) { - future.complete(null); - e.printStackTrace(); - } + plugin.getScheduler().executeAsync(() -> { + try { + future.complete(plugin.getStorageProvider().loadState(player.getUniqueId())); + } catch (Exception e) { + future.complete(null); + e.printStackTrace(); } - }.runTaskAsynchronously(plugin); + }); } return future; } diff --git a/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/region/RegionBlockListener.java b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/region/RegionBlockListener.java index 4e71c6bc2..e5444fb35 100644 --- a/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/region/RegionBlockListener.java +++ b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/region/RegionBlockListener.java @@ -7,6 +7,7 @@ import dev.aurelium.auraskills.bukkit.source.BlockLeveler; import dev.aurelium.auraskills.bukkit.util.BlockFaceUtil; import dev.aurelium.auraskills.common.config.Option; +import dev.aurelium.auraskills.common.scheduler.Task; import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.block.BlockFace; @@ -21,8 +22,8 @@ import org.bukkit.event.block.BlockPlaceEvent; import org.bukkit.event.entity.EntityChangeBlockEvent; import org.bukkit.event.world.StructureGrowEvent; -import org.bukkit.scheduler.BukkitRunnable; +import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Predicate; @@ -68,22 +69,22 @@ public void onSandFall(EntityChangeBlockEvent event) { regionManager.removePlacedBlock(block); Entity entity = event.getEntity(); AtomicInteger counter = new AtomicInteger(); - new BukkitRunnable() { - @Override - public void run() { - Block currentBlock = entity.getLocation().getBlock(); - if (entity.isDead() || !entity.isValid()) { - if (currentBlock.getType() == type) { - regionManager.addPlacedBlock(entity.getLocation().getBlock()); - } - cancel(); - } else if (currentBlock.getType().toString().contains("WEB")) { - cancel(); - } else if (counter.incrementAndGet() >= 200) { - cancel(); + + final Task[] taskHolder = new Task[1]; + + taskHolder[0] = plugin.getScheduler().timerAtEntity(entity, () -> { + Block currentBlock = entity.getLocation().getBlock(); + if (entity.isDead() || !entity.isValid()) { + if (currentBlock.getType() == type) { + regionManager.addPlacedBlock(entity.getLocation().getBlock()); } + taskHolder[0].cancel(); + } else if (currentBlock.getType().toString().contains("WEB")) { + taskHolder[0].cancel(); + } else if (counter.incrementAndGet() >= 200) { + taskHolder[0].cancel(); } - }.runTaskTimer(plugin, 1L, 1L); + }, 50, 50, TimeUnit.MILLISECONDS); } } } @@ -148,18 +149,15 @@ private void checkTallPlant(Block block, int num, Predicate isMaterial private void checkSupportBelow(Block block) { // Check if the block above requires support Block above = block.getRelative(BlockFace.UP); - SkillSource skillSource = blockLeveler.getSource(block, BlockXpSource.BlockTriggers.BREAK); + SkillSource skillSource = blockLeveler.getSource(above, BlockXpSource.BlockTriggers.BREAK); BlockXpSource source = skillSource == null ? null : skillSource.source(); if (source != null && source.requiresSupportBlock(BlockXpSource.SupportBlockType.BELOW) && regionManager.isPlacedBlock(above)) { - new BukkitRunnable() { - @Override - public void run() { - // Remove if block was destroyed - if (blockLeveler.isDifferentSource(block, source, BlockXpSource.BlockTriggers.BREAK)) { - regionManager.removePlacedBlock(above); - } + plugin.getScheduler().scheduleAtLocation(above.getLocation(), () -> { + // Remove if block was destroyed + if (blockLeveler.isDifferentSource(above, source, BlockXpSource.BlockTriggers.BREAK)) { + regionManager.removePlacedBlock(above); } - }.runTaskLater(plugin, 1); + }, 50, TimeUnit.MILLISECONDS); } } @@ -167,18 +165,15 @@ private void checkSupportSide(Block block) { // Check each side for (BlockFace face : BlockFaceUtil.getBlockSides()) { Block checkedBlock = block.getRelative(face); - SkillSource skillSource = blockLeveler.getSource(block, BlockXpSource.BlockTriggers.BREAK); + SkillSource skillSource = blockLeveler.getSource(checkedBlock, BlockXpSource.BlockTriggers.BREAK); BlockXpSource source = skillSource == null ? null : skillSource.source(); if (source != null && source.requiresSupportBlock(BlockXpSource.SupportBlockType.SIDE) && regionManager.isPlacedBlock(checkedBlock)) { - new BukkitRunnable() { - @Override - public void run() { - // Remove if block was destroyed - if (blockLeveler.isDifferentSource(block, source, BlockXpSource.BlockTriggers.BREAK)) { - regionManager.removePlacedBlock(block); - } + plugin.getScheduler().scheduleAtLocation(checkedBlock.getLocation(), () -> { + // Remove if block was destroyed + if (blockLeveler.isDifferentSource(checkedBlock, source, BlockXpSource.BlockTriggers.BREAK)) { + regionManager.removePlacedBlock(checkedBlock); } - }.runTaskLater(plugin, 1); + }, 50, TimeUnit.MILLISECONDS); } } } diff --git a/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/skills/healing/HealingAbilities.java b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/skills/healing/HealingAbilities.java index 7cd377e7b..1cf0d1451 100644 --- a/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/skills/healing/HealingAbilities.java +++ b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/skills/healing/HealingAbilities.java @@ -15,9 +15,9 @@ import org.bukkit.event.entity.EntityRegainHealthEvent; import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.event.player.PlayerRespawnEvent; -import org.bukkit.scheduler.BukkitRunnable; import java.util.Locale; +import java.util.concurrent.TimeUnit; public class HealingAbilities extends AbilityImpl { @@ -52,6 +52,7 @@ public void lifeEssence(EntityRegainHealthEvent event) { @EventHandler public void revival(PlayerRespawnEvent event) { + // TODO: PlayerRespawnEvent doesn't exists on Folia var ability = Abilities.REVIVAL; if (isDisabled(ability)) return; @@ -76,13 +77,11 @@ public void revival(PlayerRespawnEvent event) { , "{value}", NumberUtil.format1(healthBonus) , "{value_2}", NumberUtil.format1(regenerationBonus))); } - new BukkitRunnable() { - @Override - public void run() { - user.removeStatModifier(REVIVAL_HEALTH_MODIFIER_NAME); - user.removeStatModifier(REVIVAL_REGEN_MODIFIER_NAME); - } - }.runTaskLater(plugin, 30 * 20); + + plugin.getScheduler().scheduleAtEntity(player, () -> { + user.removeStatModifier(REVIVAL_HEALTH_MODIFIER_NAME); + user.removeStatModifier(REVIVAL_REGEN_MODIFIER_NAME); + }, 30, TimeUnit.SECONDS); } @EventHandler(priority = EventPriority.LOW) From f6f62ec700ad4ef1cc2377d3462301a6b419b0c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erik=20Szab=C3=B3?= Date: Thu, 24 Oct 2024 15:41:08 +0200 Subject: [PATCH 7/8] Fix update checker using wrong schedulers --- .../auraskills/bukkit/listeners/PlayerJoinQuit.java | 4 ++-- .../aurelium/auraskills/bukkit/util/UpdateChecker.java | 9 ++++----- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/listeners/PlayerJoinQuit.java b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/listeners/PlayerJoinQuit.java index 506a3b097..aed8e7a0e 100644 --- a/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/listeners/PlayerJoinQuit.java +++ b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/listeners/PlayerJoinQuit.java @@ -96,7 +96,7 @@ private void detectUserLanguage(User user, Player player) { private void sendUpdateMessage(Player player) { // Use a delayed task to give time for permission plugins to load data - plugin.getServer().getScheduler().runTaskLater(plugin, () -> { + plugin.getScheduler().scheduleSync(() -> { if (!plugin.configBoolean(Option.CHECK_FOR_UPDATES)) { return; } @@ -111,7 +111,7 @@ private void sendUpdateMessage(Player player) { player.sendMessage(plugin.getPrefix(plugin.getDefaultLanguage()) + ChatColor.WHITE + "Download it on Spigot: " + ChatColor.YELLOW + "" + ChatColor.UNDERLINE + "https://spigotmc.org/resources/" + plugin.getResourceId()); } }); - }, 40L); + }, 2L, TimeUnit.SECONDS); } } diff --git a/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/util/UpdateChecker.java b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/util/UpdateChecker.java index cb1b9c0e6..b7cc985e0 100644 --- a/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/util/UpdateChecker.java +++ b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/util/UpdateChecker.java @@ -1,7 +1,6 @@ package dev.aurelium.auraskills.bukkit.util; -import org.bukkit.Bukkit; -import org.bukkit.plugin.Plugin; +import dev.aurelium.auraskills.bukkit.AuraSkills; import java.io.IOException; import java.io.InputStream; @@ -11,16 +10,16 @@ public class UpdateChecker { - private final Plugin plugin; + private final AuraSkills plugin; private final int resourceId; - public UpdateChecker(Plugin plugin, int resourceId) { + public UpdateChecker(AuraSkills plugin, int resourceId) { this.plugin = plugin; this.resourceId = resourceId; } public void getVersion(final Consumer consumer) { - Bukkit.getScheduler().runTaskAsynchronously(this.plugin, () -> { + plugin.getScheduler().executeAsync(() -> { try (InputStream inputStream = new URL("https://api.spigotmc.org/legacy/update.php?resource=" + this.resourceId).openStream(); Scanner scanner = new Scanner(inputStream)) { if (scanner.hasNext()) { consumer.accept(scanner.nextLine()); From 6be69bc8ec7798db8028b5355227428120476ece Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erik=20Szab=C3=B3?= Date: Fri, 25 Oct 2024 08:43:03 +0200 Subject: [PATCH 8/8] Update to latest Slate for proper folia support in menus --- .../main/java/dev/aurelium/auraskills/bukkit/AuraSkills.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/AuraSkills.java b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/AuraSkills.java index 65fa10f3b..f0158a616 100644 --- a/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/AuraSkills.java +++ b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/AuraSkills.java @@ -78,7 +78,6 @@ import dev.aurelium.auraskills.common.message.type.CommandMessage; import dev.aurelium.auraskills.common.migration.MigrationManager; import dev.aurelium.auraskills.common.reward.RewardManager; -import dev.aurelium.auraskills.common.scheduler.Scheduler; import dev.aurelium.auraskills.common.skill.SkillLoader; import dev.aurelium.auraskills.common.skill.SkillManager; import dev.aurelium.auraskills.common.skill.SkillRegistry; @@ -97,6 +96,7 @@ import dev.aurelium.auraskills.common.util.file.FileUtil; import dev.aurelium.slate.Slate; import dev.aurelium.slate.inv.InventoryManager; +import dev.aurelium.slate.scheduler.Scheduler; import net.kyori.adventure.platform.bukkit.BukkitAudiences; import org.bstats.bukkit.Metrics; import org.bukkit.Bukkit; @@ -223,7 +223,7 @@ public void onEnable() { leaderboardManager = new LeaderboardManager(this); uiProvider = new BukkitUiProvider(this); modifierManager = new BukkitModifierManager(this); - inventoryManager = new InventoryManager(this, dev.aurelium.slate.scheduler.Scheduler.createScheduler(this)); + inventoryManager = new InventoryManager(this, Scheduler.createScheduler(this)); inventoryManager.init(); rewardManager = new BukkitRewardManager(this); // Loaded later lootTableManager = new LootTableManager(this); // Loaded later