From e3d5ebab8b86a83780b1c35c2a5d658594e318d8 Mon Sep 17 00:00:00 2001 From: D3v1s0m <49519439+D3v1s0m@users.noreply.github.com> Date: Wed, 17 May 2023 18:47:01 +0530 Subject: [PATCH 1/4] cancel tasks on plugin disable --- .../main/java/lol/pyr/znpcsplus/ZNpcsPlus.java | 1 + .../pyr/znpcsplus/reflection/Reflections.java | 12 ++++++++++++ .../pyr/znpcsplus/scheduling/FoliaScheduler.java | 16 ++++++++++++++++ .../znpcsplus/scheduling/SpigotScheduler.java | 5 +++++ .../pyr/znpcsplus/scheduling/TaskScheduler.java | 2 ++ 5 files changed, 36 insertions(+) diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/ZNpcsPlus.java b/plugin/src/main/java/lol/pyr/znpcsplus/ZNpcsPlus.java index fcf2d3b..750a0f4 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/ZNpcsPlus.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/ZNpcsPlus.java @@ -212,6 +212,7 @@ public class ZNpcsPlus extends JavaPlugin implements ZApi { @Override public void onDisable() { if (!enabled) return; + scheduler.cancelAll(); npcRegistry.save(); ZApiProvider.unregister(); Bukkit.getOnlinePlayers().forEach(userManager::remove); diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/reflection/Reflections.java b/plugin/src/main/java/lol/pyr/znpcsplus/reflection/Reflections.java index c9e450b..2af7a3e 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/reflection/Reflections.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/reflection/Reflections.java @@ -117,6 +117,18 @@ public final class Reflections { .setStrict(FoliaUtil.isFolia()) .toMethodReflection(); + public static final ReflectionLazyLoader FOLIA_CANCEL_ASYNC_TASKS = + new ReflectionBuilder(ASYNC_SCHEDULER_CLASS) + .withMethodName("cancelTasks") + .setStrict(FoliaUtil.isFolia()) + .toMethodReflection(); + + public static final ReflectionLazyLoader FOLIA_CANCEL_GLOBAL_TASKS = + new ReflectionBuilder(GLOBAL_REGION_SCHEDULER_CLASS) + .withMethodName("cancelTasks") + .setStrict(FoliaUtil.isFolia()) + .toMethodReflection(); + public static final ReflectionLazyLoader FOLIA_TELEPORT_ASYNC = new ReflectionBuilder(Entity.class) .withMethodName("teleportAsync") diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/scheduling/FoliaScheduler.java b/plugin/src/main/java/lol/pyr/znpcsplus/scheduling/FoliaScheduler.java index 6d8e742..6bf978a 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/scheduling/FoliaScheduler.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/scheduling/FoliaScheduler.java @@ -41,5 +41,21 @@ public class FoliaScheduler extends TaskScheduler { throw new RuntimeException(e); } } + + @Override + public void cancelAll() { + try { + Object asyncScheduler = Reflections.FOLIA_GET_ASYNC_SCHEDULER.get().invoke(null); + Reflections.FOLIA_CANCEL_ASYNC_TASKS.get().invoke(asyncScheduler, plugin); + } catch (IllegalAccessException | InvocationTargetException e) { + throw new RuntimeException(e); + } + try { + Object globalScheduler = Reflections.FOLIA_GET_GLOBAL_REGION_SCHEDULER.get().invoke(null); + Reflections.FOLIA_CANCEL_GLOBAL_TASKS.get().invoke(globalScheduler, plugin); + } catch (IllegalAccessException | InvocationTargetException e) { + throw new RuntimeException(e); + } + } } diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/scheduling/SpigotScheduler.java b/plugin/src/main/java/lol/pyr/znpcsplus/scheduling/SpigotScheduler.java index 10a420c..dc15536 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/scheduling/SpigotScheduler.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/scheduling/SpigotScheduler.java @@ -22,4 +22,9 @@ public class SpigotScheduler extends TaskScheduler { public void runDelayedTimerAsync(Runnable runnable, long delay, long ticks) { Bukkit.getScheduler().runTaskTimerAsynchronously(plugin, runnable, delay, ticks); } + + @Override + public void cancelAll() { + Bukkit.getScheduler().cancelTasks(plugin); + } } diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/scheduling/TaskScheduler.java b/plugin/src/main/java/lol/pyr/znpcsplus/scheduling/TaskScheduler.java index af97271..d6e1fe3 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/scheduling/TaskScheduler.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/scheduling/TaskScheduler.java @@ -14,4 +14,6 @@ public abstract class TaskScheduler { public abstract void runLaterAsync(Runnable runnable, long ticks); public abstract void runDelayedTimerAsync(Runnable runnable, long delay, long ticks); + + public abstract void cancelAll(); } From 14ff80b3efc4802f7112b652d3b8b798c1e02837 Mon Sep 17 00:00:00 2001 From: D3v1s0m <49519439+D3v1s0m@users.noreply.github.com> Date: Sun, 21 May 2023 08:48:28 +0530 Subject: [PATCH 2/4] changed load order - fixes plugin not loading at all --- .../java/lol/pyr/znpcsplus/ZNpcsPlus.java | 23 +++++++++++-------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/ZNpcsPlus.java b/plugin/src/main/java/lol/pyr/znpcsplus/ZNpcsPlus.java index 750a0f4..58280d0 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/ZNpcsPlus.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/ZNpcsPlus.java @@ -110,10 +110,6 @@ public class ZNpcsPlus extends JavaPlugin implements ZApi { log(ChatColor.WHITE + " * Initializing Adventure..."); adventure = BukkitAudiences.create(this); - log(ChatColor.WHITE + " * Initializing PacketEvents..."); - packetEvents.getEventManager().registerListener(new InteractionPacketListener(userManager, npcRegistry), PacketListenerPriority.MONITOR); - packetEvents.init(); - metadataFactory = setupMetadataFactory(); PacketFactory packetFactory = setupPacketFactory(); @@ -125,20 +121,15 @@ public class ZNpcsPlus extends JavaPlugin implements ZApi { log(ChatColor.WHITE + " * Defining NPC types..."); NpcTypeImpl.defineTypes(); - log(ChatColor.WHITE + " * Starting tasks & registering components..."); + log(ChatColor.WHITE + " * Registering components..."); getServer().getMessenger().registerOutgoingPluginChannel(this, "BungeeCord"); new Metrics(this, PLUGIN_ID); scheduler = FoliaUtil.isFolia() ? new FoliaScheduler(this) : new SpigotScheduler(this); BungeeUtil bungeeUtil = new BungeeUtil(this); userManager = new UserManager(); Bukkit.getOnlinePlayers().forEach(userManager::get); - pluginManager.registerEvents(new UserListener(userManager), this); - scheduler.runDelayedTimerAsync(new NpcVisibilityTask(npcRegistry, configManager), 60L, 10L); - skinCache = new SkinCache(configManager); - scheduler.runDelayedTimerAsync(new SkinCacheCleanTask(skinCache), 1200, 1200); - registerCommands(); if (configManager.getConfig().checkForUpdates()) { UpdateChecker updateChecker = new UpdateChecker(this.getDescription()); @@ -151,6 +142,18 @@ public class ZNpcsPlus extends JavaPlugin implements ZApi { npcRegistry = new NpcRegistryImpl(configManager, this, packetFactory, actionRegistry); npcRegistry.reload(); + log(ChatColor.WHITE + " * Initializing PacketEvents..."); + packetEvents.getEventManager().registerListener(new InteractionPacketListener(userManager, npcRegistry), PacketListenerPriority.MONITOR); + packetEvents.init(); + + log(ChatColor.WHITE + " * Starting tasks..."); + scheduler.runDelayedTimerAsync(new NpcVisibilityTask(npcRegistry, configManager), 60L, 10L); + skinCache = new SkinCache(configManager); + scheduler.runDelayedTimerAsync(new SkinCacheCleanTask(skinCache), 1200, 1200); + + log(ChatColor.WHITE + " * Registering commands..."); + registerCommands(); + ZApiProvider.register(this); enabled = true; log(ChatColor.WHITE + " * Loading complete! (" + (System.currentTimeMillis() - before) + "ms)"); From 8129405de8a56da9665e3a437ee0205f09dd1a22 Mon Sep 17 00:00:00 2001 From: D3v1s0m <49519439+D3v1s0m@users.noreply.github.com> Date: Sun, 21 May 2023 08:53:26 +0530 Subject: [PATCH 3/4] temp fix for null values in setting property --- plugin/src/main/java/lol/pyr/znpcsplus/npc/NpcImpl.java | 1 + 1 file changed, 1 insertion(+) diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/npc/NpcImpl.java b/plugin/src/main/java/lol/pyr/znpcsplus/npc/NpcImpl.java index 14e0b0a..bc3d972 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/npc/NpcImpl.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/npc/NpcImpl.java @@ -113,6 +113,7 @@ public class NpcImpl extends Viewable implements Npc { } public void setProperty(EntityPropertyImpl key, T value) { + if (value == null) return; if (value.equals(key.getDefaultValue())) removeProperty(key); else propertyMap.put(key, value); _refreshMeta(); From 329f9fe86c6313876ee10e4def0d608fe8cb3e20 Mon Sep 17 00:00:00 2001 From: D3v1s0m <49519439+D3v1s0m@users.noreply.github.com> Date: Sun, 21 May 2023 09:40:01 +0530 Subject: [PATCH 4/4] Added hologram offset --- .../java/lol/pyr/znpcsplus/ZNpcsPlus.java | 4 +- .../commands/hologram/HoloOffsetCommand.java | 38 +++++++++++++++++++ .../pyr/znpcsplus/hologram/HologramImpl.java | 12 +++++- .../znpcsplus/storage/yaml/YamlStorage.java | 7 ++-- 4 files changed, 56 insertions(+), 5 deletions(-) create mode 100644 plugin/src/main/java/lol/pyr/znpcsplus/commands/hologram/HoloOffsetCommand.java diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/ZNpcsPlus.java b/plugin/src/main/java/lol/pyr/znpcsplus/ZNpcsPlus.java index 58280d0..29d1176 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/ZNpcsPlus.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/ZNpcsPlus.java @@ -8,6 +8,7 @@ import io.github.retrooper.packetevents.factory.spigot.SpigotPacketEventsBuilder import lol.pyr.director.adventure.command.CommandManager; import lol.pyr.director.adventure.command.MultiCommand; import lol.pyr.director.adventure.parse.primitive.BooleanParser; +import lol.pyr.director.adventure.parse.primitive.DoubleParser; import lol.pyr.director.adventure.parse.primitive.IntegerParser; import lol.pyr.znpcsplus.api.ZApi; import lol.pyr.znpcsplus.api.ZApiProvider; @@ -231,6 +232,7 @@ public class ZNpcsPlus extends JavaPlugin implements ZApi { manager.registerParser(NpcEntryImpl.class, new NpcEntryParser(npcRegistry, context -> {})); manager.registerParser(EntityPropertyImpl.class, new EntityPropertyParser(context -> {})); manager.registerParser(Integer.class, new IntegerParser(context -> {})); + manager.registerParser(Double.class, new DoubleParser(context -> {})); manager.registerParser(Boolean.class, new BooleanParser(context -> {})); manager.registerParser(NamedTextColor.class, new NamedTextColorParser(context -> {})); @@ -254,7 +256,7 @@ public class ZNpcsPlus extends JavaPlugin implements ZApi { .addSubcommand("info", new HoloInfoCommand(npcRegistry)) .addSubcommand("insert", new HoloInsertCommand(npcRegistry, textSerializer)) .addSubcommand("set", new HoloSetCommand(npcRegistry, textSerializer)) - ) + .addSubcommand("offset", new HoloOffsetCommand(npcRegistry))) ); } diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/commands/hologram/HoloOffsetCommand.java b/plugin/src/main/java/lol/pyr/znpcsplus/commands/hologram/HoloOffsetCommand.java new file mode 100644 index 0000000..c1dd0af --- /dev/null +++ b/plugin/src/main/java/lol/pyr/znpcsplus/commands/hologram/HoloOffsetCommand.java @@ -0,0 +1,38 @@ +package lol.pyr.znpcsplus.commands.hologram; + +import lol.pyr.director.adventure.command.CommandContext; +import lol.pyr.director.adventure.command.CommandHandler; +import lol.pyr.director.common.command.CommandExecutionException; +import lol.pyr.znpcsplus.hologram.HologramImpl; +import lol.pyr.znpcsplus.npc.NpcEntryImpl; +import lol.pyr.znpcsplus.npc.NpcRegistryImpl; + +import java.util.Collections; +import java.util.List; + +public class HoloOffsetCommand implements CommandHandler { + private final NpcRegistryImpl npcRegistry; + + public HoloOffsetCommand(NpcRegistryImpl npcRegistry) { + this.npcRegistry = npcRegistry; + } + + @Override + public void run(CommandContext context) throws CommandExecutionException { + context.setUsage(context.getLabel() + " holo offset "); + HologramImpl hologram = context.parse(NpcEntryImpl.class).getNpc().getHologram(); + double offset = context.parse(Double.class); + hologram.setOffset(offset); + context.send("NPC hologram offset set!"); + } + + @Override + public List suggest(CommandContext context) throws CommandExecutionException { + if (context.argSize() == 1) return context.suggestCollection(npcRegistry.modifiableIds()); + if (context.argSize() == 2) { + HologramImpl hologram = context.suggestionParse(0, NpcEntryImpl.class).getNpc().getHologram(); + return context.suggestLiteral(String.valueOf(hologram.getOffset())); + } + return Collections.emptyList(); + } +} diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/hologram/HologramImpl.java b/plugin/src/main/java/lol/pyr/znpcsplus/hologram/HologramImpl.java index fcaecf3..d2345d0 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/hologram/HologramImpl.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/hologram/HologramImpl.java @@ -16,6 +16,7 @@ public class HologramImpl extends Viewable implements Hologram { private final ConfigManager configManager; private final PacketFactory packetFactory; + private double offset = 0.0; private ZLocation location; private final List lines = new ArrayList<>(); @@ -79,10 +80,19 @@ public class HologramImpl extends Viewable implements Hologram { private void relocateLines(HologramLine newLine) { final double lineSpacing = configManager.getConfig().lineSpacing(); - double height = location.getY() + (lines.size() - 1) * lineSpacing; + double height = location.getY() + (lines.size() - 1) * lineSpacing + getOffset(); for (HologramLine line : lines) { line.setLocation(location.withY(height), line == newLine ? Collections.emptySet() : getViewers()); height -= lineSpacing; } } + + public void setOffset(double offset) { + this.offset = offset; + relocateLines(); + } + + public double getOffset() { + return offset; + } } diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/storage/yaml/YamlStorage.java b/plugin/src/main/java/lol/pyr/znpcsplus/storage/yaml/YamlStorage.java index d098f2a..db0bc1a 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/storage/yaml/YamlStorage.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/storage/yaml/YamlStorage.java @@ -51,8 +51,8 @@ public class YamlStorage implements NpcStorage { npc.UNSAFE_setProperty(property, property.deserialize(properties.getString(key))); } } - - for (String line : config.getStringList("hologram")) npc.getHologram().addLine(MiniMessage.miniMessage().deserialize(line)); + npc.getHologram().setOffset(config.getDouble("hologram.offset", 0.0)); + for (String line : config.getStringList("hologram.lines")) npc.getHologram().addLine(MiniMessage.miniMessage().deserialize(line)); for (String s : config.getStringList("actions")) npc.addAction(actionRegistry.deserialize(s)); NpcEntryImpl entry = new NpcEntryImpl(config.getString("id"), npc); @@ -84,11 +84,12 @@ public class YamlStorage implements NpcStorage { config.set("properties." + property.getName(), property.serialize(npc)); } + if (npc.getHologram().getOffset() != 0.0) config.set("hologram.offset", npc.getHologram().getOffset()); List lines = new ArrayList<>(); for (HologramLine line : npc.getHologram().getLines()) { lines.add(MiniMessage.miniMessage().serialize(line.getText())); } - config.set("hologram", lines); + config.set("hologram.lines", lines); config.set("actions", npc.getActions().stream() .map(actionRegistry::serialize) .filter(Objects::nonNull)