From 0f42ab6e89f5cb544b4ccbb36b1ac0f7b5d829ee Mon Sep 17 00:00:00 2001 From: TheJokerDev Date: Mon, 9 Aug 2021 14:29:05 -0600 Subject: [PATCH] Upload code (v.1.0.3) Upload of code. By TheJokerDev. --- .gitignore | 113 ++ pom.xml | 103 ++ .../me/TheJokerDev/futureholograms/Main.java | 105 ++ .../commands/FHologramsCmd.java | 113 ++ .../futureholograms/commands/SubCommand.java | 17 + .../commands/subcmds/CreateCmd.java | 66 + .../commands/subcmds/ListCmd.java | 61 + .../commands/subcmds/ReloadCmd.java | 78 + .../commands/subcmds/RemoveCmd.java | 67 + .../subcmds/SetExactlyLocationCmd.java | 70 + .../commands/subcmds/SetLocationCmd.java | 72 + .../futureholograms/holo/FHologram.java | 384 +++++ .../holo/HologramsManager.java | 38 + .../listeners/LoginListeners.java | 42 + .../listeners/WorldListeners.java | 32 + .../futureholograms/utils/LocationUtil.java | 53 + .../futureholograms/utils/Utils.java | 175 ++ .../me/TheJokerDev/other/DefaultFontInfo.java | 129 ++ .../other/FileConfigurationUtil.java | 322 ++++ .../java/me/TheJokerDev/other/XSound.java | 1504 +++++++++++++++++ src/main/resources/config.yml | 65 + src/main/resources/holograms.yml | 26 + src/main/resources/plugin.yml | 13 + 23 files changed, 3648 insertions(+) create mode 100644 .gitignore create mode 100644 pom.xml create mode 100644 src/main/java/me/TheJokerDev/futureholograms/Main.java create mode 100644 src/main/java/me/TheJokerDev/futureholograms/commands/FHologramsCmd.java create mode 100644 src/main/java/me/TheJokerDev/futureholograms/commands/SubCommand.java create mode 100644 src/main/java/me/TheJokerDev/futureholograms/commands/subcmds/CreateCmd.java create mode 100644 src/main/java/me/TheJokerDev/futureholograms/commands/subcmds/ListCmd.java create mode 100644 src/main/java/me/TheJokerDev/futureholograms/commands/subcmds/ReloadCmd.java create mode 100644 src/main/java/me/TheJokerDev/futureholograms/commands/subcmds/RemoveCmd.java create mode 100644 src/main/java/me/TheJokerDev/futureholograms/commands/subcmds/SetExactlyLocationCmd.java create mode 100644 src/main/java/me/TheJokerDev/futureholograms/commands/subcmds/SetLocationCmd.java create mode 100644 src/main/java/me/TheJokerDev/futureholograms/holo/FHologram.java create mode 100644 src/main/java/me/TheJokerDev/futureholograms/holo/HologramsManager.java create mode 100644 src/main/java/me/TheJokerDev/futureholograms/listeners/LoginListeners.java create mode 100644 src/main/java/me/TheJokerDev/futureholograms/listeners/WorldListeners.java create mode 100644 src/main/java/me/TheJokerDev/futureholograms/utils/LocationUtil.java create mode 100644 src/main/java/me/TheJokerDev/futureholograms/utils/Utils.java create mode 100644 src/main/java/me/TheJokerDev/other/DefaultFontInfo.java create mode 100644 src/main/java/me/TheJokerDev/other/FileConfigurationUtil.java create mode 100644 src/main/java/me/TheJokerDev/other/XSound.java create mode 100644 src/main/resources/config.yml create mode 100644 src/main/resources/holograms.yml create mode 100644 src/main/resources/plugin.yml diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4788b4b --- /dev/null +++ b/.gitignore @@ -0,0 +1,113 @@ +# User-specific stuff +.idea/ + +*.iml +*.ipr +*.iws + +# IntelliJ +out/ + +# Compiled class file +*.class + +# Log file +*.log + +# BlueJ files +*.ctxt + +# Package Files # +*.jar +*.war +*.nar +*.ear +*.zip +*.tar.gz +*.rar + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* + +*~ + +# temporary files which can be created if a process still has a handle open of a deleted file +.fuse_hidden* + +# KDE directory preferences +.directory + +# Linux trash folder which might appear on any partition or disk +.Trash-* + +# .nfs files are created when an open file is removed but is still being accessed +.nfs* + +# General +.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + +# Thumbnails +._* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +# Windows thumbnail cache files +Thumbs.db +Thumbs.db:encryptable +ehthumbs.db +ehthumbs_vista.db + +# Dump file +*.stackdump + +# Folder config file +[Dd]esktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Windows Installer files +*.cab +*.msi +*.msix +*.msm +*.msp + +# Windows shortcuts +*.lnk + +target/ + +pom.xml.tag +pom.xml.releaseBackup +pom.xml.versionsBackup +pom.xml.next + +release.properties +dependency-reduced-pom.xml +buildNumber.properties +.mvn/timing.properties +.mvn/wrapper/maven-wrapper.jar +.flattened-pom.xml + +# Common working directory +run/ diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..de3e4bc --- /dev/null +++ b/pom.xml @@ -0,0 +1,103 @@ + + + 4.0.0 + + me.TheJokerDev + FutureHolograms + 1.0.3 + jar + + FutureHolograms + + Create custom holograms with uniques options. + + 1.8 + UTF-8 + + https://github.com/TheJokerDev + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.1 + + ${java.version} + ${java.version} + + + + org.apache.maven.plugins + maven-shade-plugin + 3.2.4 + + + package + + shade + + + false + + + + + + + + src/main/resources + true + + + + + + + spigotmc-repo + https://hub.spigotmc.org/nexus/content/repositories/snapshots/ + + + sonatype + https://oss.sonatype.org/content/groups/public/ + + + placeholderapi + http://repo.extendedclip.com/content/repositories/placeholderapi/ + + + codemc-repo + https://repo.codemc.io/repository/maven-public/ + + + + + + org.spigotmc + spigot-api + 1.17.1-R0.1-SNAPSHOT + provided + + + org.spigotmc + spigot + system + 1.17.1-R0.1-SNAPSHOT + ${user.home}/Google Drive/JavaProjects/IdeaProjects/purpur-1.17.1.jar + + + me.clip + placeholderapi + 2.10.9 + provided + + + com.gmail.filoghost.holographicdisplays + holographicdisplays-api + 2.4.0 + provided + + + diff --git a/src/main/java/me/TheJokerDev/futureholograms/Main.java b/src/main/java/me/TheJokerDev/futureholograms/Main.java new file mode 100644 index 0000000..9fcab12 --- /dev/null +++ b/src/main/java/me/TheJokerDev/futureholograms/Main.java @@ -0,0 +1,105 @@ +package me.TheJokerDev.futureholograms; + +import me.TheJokerDev.futureholograms.commands.FHologramsCmd; +import me.TheJokerDev.futureholograms.holo.FHologram; +import me.TheJokerDev.futureholograms.holo.HologramsManager; +import me.TheJokerDev.futureholograms.listeners.LoginListeners; +import me.TheJokerDev.futureholograms.listeners.WorldListeners; +import me.TheJokerDev.futureholograms.utils.Utils; +import org.bukkit.Bukkit; +import org.bukkit.event.Listener; +import org.bukkit.plugin.PluginManager; +import org.bukkit.plugin.java.JavaPlugin; + +import java.util.Arrays; + +public final class Main extends JavaPlugin { + private static Main plugin; + private static boolean papiLoaded = true; + + @Override + public void onEnable() { + saveDefaultConfig(); + plugin = this; + long ms = System.currentTimeMillis(); + log(0, "{prefix}&7Loading plugin..."); + PluginManager pm = getServer().getPluginManager(); + + log(0, "{prefix}&7Checking dependencies..."); + if (!pm.isPluginEnabled("PlaceholderAPI")){ + log(1, "&cYou need to install PlaceholderAPI to work."); + papiLoaded = false; + pm.disablePlugin(this); + return; + } else if (!pm.isPluginEnabled("HolographicDisplays")){ + log(1, "&cYou need to force install HolographicDisplays to work."); + pm.disablePlugin(this); + return; + } + log(0, "{prefix}&aDependencies checked and hooked!"); + + log(0, "{prefix}&7Loading commands..."); + getCommand("futureholograms").setExecutor(new FHologramsCmd()); + getCommand("futureholograms").setTabCompleter(new FHologramsCmd()); + log(0, "{prefix}&aCommands loaded!"); + + log(0, "{prefix}&7Loading holograms..."); + HologramsManager.initHolograms(); + log(0, "{prefix}&aHolograms loaded!"); + + log(0, "{prefix}&7Loading listeners..."); + listeners(new LoginListeners(), new WorldListeners()); + log(0, "{prefix}&aListeners loaded sucessfully!"); + + ms = System.currentTimeMillis()-ms; + Utils.sendMessage(Bukkit.getConsoleSender(), + "{prefix}&aPlugin fully loaded and started!", + "&b&l=========================================", + "&fThanks to use my plugin. Plugin loaded in", + "&f"+ms/1000+" seconds.", + "", + "&a Made with love, by TheJokerDev &c<3", + "&b&l=========================================" + ); + } + + public static void listeners(Listener... list){ + Arrays.stream(list).forEach(l-> Bukkit.getPluginManager().registerEvents(l, getPlugin())); + } + + + public static void log(int mode, String msg){ + if (mode == 0){ + Utils.sendMessage(Bukkit.getConsoleSender(), msg); + } else if (mode == 1){ + Utils.sendMessage(Bukkit.getConsoleSender(), "&c&lError: &7"+msg); + } else if (mode == 2){ + if (getPlugin().getConfig().getBoolean("debug")) { + Utils.sendMessage(Bukkit.getConsoleSender(), "&e&lDebug: &7" + msg); + } + } + } + + public static boolean isPapiLoaded() { + return papiLoaded; + } + + public static Main getPlugin() { + return plugin; + } + + public static String getPrefix(){ + return Utils.getConfig().getString("prefix"); + } + + @Override + public void onDisable() { + log(0, "{prefix}&7Disabling holograms..."); + for (FHologram holo : HologramsManager.getHolograms()){ + holo.deleteAll(); + HologramsManager.hologramHashMap.remove(holo.getName()); + } + log(0, "{prefix}&cHolograms disabled!"); + log(0, "{prefix}&cDisabling plugin..."); + } +} diff --git a/src/main/java/me/TheJokerDev/futureholograms/commands/FHologramsCmd.java b/src/main/java/me/TheJokerDev/futureholograms/commands/FHologramsCmd.java new file mode 100644 index 0000000..8fd8fd3 --- /dev/null +++ b/src/main/java/me/TheJokerDev/futureholograms/commands/FHologramsCmd.java @@ -0,0 +1,113 @@ +package me.TheJokerDev.futureholograms.commands; + +import me.TheJokerDev.futureholograms.commands.subcmds.*; +import me.TheJokerDev.futureholograms.utils.Utils; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.command.TabCompleter; +import org.bukkit.util.StringUtil; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.*; + +public class FHologramsCmd implements CommandExecutor, TabCompleter { + private final HashMap subCommands; + + public FHologramsCmd(){ + subCommands = new HashMap<>(); + loadSubCommands(); + } + + void loadSubCommands(){ + subCommands.put("create", new CreateCmd()); + subCommands.put("reload", new ReloadCmd()); + subCommands.put("delete", new RemoveCmd()); + subCommands.put("setlocation", new SetLocationCmd()); + subCommands.put("setexactlylocation", new SetExactlyLocationCmd()); + subCommands.put("list", new ListCmd()); + } + + @Override + public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) { + if (!sender.hasPermission("futureholograms.admin")){ + Utils.sendMessage(sender, "messages.noPermission"); + return true; + } + + if (args == null || args.length < 1) { + sendHelp(sender, label); + return true; + } + if (args[0].equalsIgnoreCase("help")) { + sendHelp(sender, label); + return true; + } + String str = args[0]; + Vector vector = new Vector<>(Arrays.asList(args)); + vector.remove(0); + args = vector.toArray(new String[0]); + if (!subCommands.containsKey(str)) { + Utils.sendMessage(sender, "messages.commandNoExists"); + return true; + } + try { + subCommands.get(str).onCommand(sender, args); + } catch (Exception exception) { + exception.printStackTrace(); + Utils.sendMessage(sender, "messages.error"); + } + return true; + } + + void sendHelp(CommandSender cmd, String label){ + + List help = Utils.getConfig().getStringList("messages.commands.help"); + List var1 = new ArrayList<>(); + + for (String s : help) { + if (s.equalsIgnoreCase("{cmd}")) { + for (SubCommand subcmd : subCommands.values()){ + var1.add(subcmd.help().replace("%alias%", label)); + } + } else { + var1.add(s); + } + } + Utils.sendMessage(cmd, var1); + } + + @Nullable + @Override + public List onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias, @NotNull String[] args) { + if (!sender.hasPermission("futureholograms.admin")){ + return null; + } + if (args.length == 1) { + List arrayList = new ArrayList<>(); + StringUtil.copyPartialMatches(args[0], subCommands.keySet(), arrayList); + Collections.sort(arrayList); + return arrayList; + } + + if (args.length >= 2) { + String str = args[0]; + Vector vector = new Vector<>(Arrays.asList(args)); + vector.remove(0); + args = vector.toArray(new String[0]); + + if (!subCommands.containsKey(str)) { + return null; + } + List list = subCommands.get(str).onTabComplete(sender, args); + + if (list == null) { + list = new ArrayList<>(); + } + + return list; + } + return null; + } +} \ No newline at end of file diff --git a/src/main/java/me/TheJokerDev/futureholograms/commands/SubCommand.java b/src/main/java/me/TheJokerDev/futureholograms/commands/SubCommand.java new file mode 100644 index 0000000..112cf80 --- /dev/null +++ b/src/main/java/me/TheJokerDev/futureholograms/commands/SubCommand.java @@ -0,0 +1,17 @@ +package me.TheJokerDev.futureholograms.commands; + +import org.bukkit.command.CommandSender; + +import java.util.List; + +public interface SubCommand { + boolean onCommand(CommandSender sender, String[] args); + + List onTabComplete(CommandSender sender, String[] args); + + String help(); + + String getPermission(); + + boolean console(); +} diff --git a/src/main/java/me/TheJokerDev/futureholograms/commands/subcmds/CreateCmd.java b/src/main/java/me/TheJokerDev/futureholograms/commands/subcmds/CreateCmd.java new file mode 100644 index 0000000..b1721fe --- /dev/null +++ b/src/main/java/me/TheJokerDev/futureholograms/commands/subcmds/CreateCmd.java @@ -0,0 +1,66 @@ +package me.TheJokerDev.futureholograms.commands.subcmds; + +import me.TheJokerDev.futureholograms.commands.SubCommand; +import me.TheJokerDev.futureholograms.holo.FHologram; +import me.TheJokerDev.futureholograms.holo.HologramsManager; +import me.TheJokerDev.futureholograms.utils.LocationUtil; +import me.TheJokerDev.futureholograms.utils.Utils; +import me.TheJokerDev.other.FileConfigurationUtil; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; + +public class CreateCmd implements SubCommand { + @Override + public boolean onCommand(CommandSender sender, String[] args) { + if (!(sender instanceof Player)){ + Utils.sendMessage(sender, "messages.onlyPlayers"); + return true; + } + Player p = (Player)sender; + if (args.length == 1){ + String var1 = args[0]; + FHologram var2 = HologramsManager.getHologram(var1); + if (var2 != null){ + Utils.sendMessage(sender, "messages.commands.create.alreadyExist"); + } + FileConfigurationUtil config = Utils.getFile("holograms.yml"); + config.add(var1+".location", LocationUtil.getString(p.getLocation(), true)); + config.add(var1+".default", "var1"); + config.add(var1+".var1.next", "var1"); + List lines = new ArrayList<>(); + lines.add("&bChange this on holograms config."); + config.add(var1+".var1.lines", lines); + config.save(); + FHologram holo = new FHologram(var1); + HologramsManager.hologramHashMap.put(var1, holo); + Utils.sendMessage(sender, "messages.commands.create.success"); + } else { + Utils.sendMessage(sender, help()); + } + return true; + } + + @Override + public List onTabComplete(CommandSender sender, String[] args) { + return null; + } + + @Override + public String help() { + return Utils.getConfig().getString("messages.commands.create.help").replace("%alias%", "fholo"); + } + + @Override + public String getPermission() { + return "futureholograms.admin.create"; + } + + @Override + public boolean console() { + return false; + } +} diff --git a/src/main/java/me/TheJokerDev/futureholograms/commands/subcmds/ListCmd.java b/src/main/java/me/TheJokerDev/futureholograms/commands/subcmds/ListCmd.java new file mode 100644 index 0000000..c65d64c --- /dev/null +++ b/src/main/java/me/TheJokerDev/futureholograms/commands/subcmds/ListCmd.java @@ -0,0 +1,61 @@ +package me.TheJokerDev.futureholograms.commands.subcmds; + +import me.TheJokerDev.futureholograms.commands.SubCommand; +import me.TheJokerDev.futureholograms.holo.FHologram; +import me.TheJokerDev.futureholograms.holo.HologramsManager; +import me.TheJokerDev.futureholograms.utils.Utils; +import org.bukkit.command.CommandSender; + +import java.util.ArrayList; +import java.util.List; + +public class ListCmd implements SubCommand { + @Override + public boolean onCommand(CommandSender sender, String[] args) { + if (args.length == 0){ + sendList(sender, "fholo"); + } else { + Utils.sendMessage(sender, help()); + } + return true; + } + + @Override + public List onTabComplete(CommandSender sender, String[] args) { + return null; + } + + @Override + public String help() { + return Utils.getConfig().getString("messages.commands.list.help").replace("%alias%", "fholo"); + } + + @Override + public String getPermission() { + return "futureholograms.admin.list"; + } + + void sendList(CommandSender cmd, String label){ + + List help = Utils.getConfig().getStringList("messages.commands.list.format"); + String format = Utils.getConfig().getString("messages.commands.list.hologramFormat"); + List var1 = new ArrayList<>(); + + for (String s : help) { + if (s.equalsIgnoreCase("{list}")) { + for (FHologram subcmd : HologramsManager.getHolograms()){ + var1.add(format.replaceAll("%name%", subcmd.getName()) + .replaceAll("%location%", subcmd.getFormattedLocation())); + } + } else { + var1.add(s); + } + } + Utils.sendMessage(cmd, var1); + } + + @Override + public boolean console() { + return true; + } +} diff --git a/src/main/java/me/TheJokerDev/futureholograms/commands/subcmds/ReloadCmd.java b/src/main/java/me/TheJokerDev/futureholograms/commands/subcmds/ReloadCmd.java new file mode 100644 index 0000000..5aa7e0c --- /dev/null +++ b/src/main/java/me/TheJokerDev/futureholograms/commands/subcmds/ReloadCmd.java @@ -0,0 +1,78 @@ +package me.TheJokerDev.futureholograms.commands.subcmds; + +import me.TheJokerDev.futureholograms.Main; +import me.TheJokerDev.futureholograms.commands.SubCommand; +import me.TheJokerDev.futureholograms.holo.FHologram; +import me.TheJokerDev.futureholograms.holo.HologramsManager; +import me.TheJokerDev.futureholograms.utils.Utils; +import org.bukkit.command.CommandSender; +import org.bukkit.util.StringUtil; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; + +public class ReloadCmd implements SubCommand { + @Override + public boolean onCommand(CommandSender sender, String[] args) { + if (args.length == 0){ + if (HologramsManager.getHolograms().length == 0) { + Utils.sendMessage(sender, "messages.commands.reload.noHolograms"); + return true; + } + HologramsManager.initHolograms(); + Utils.sendMessage(sender, "messages.commands.reload.success"); + } else if (args.length == 1){ + String var1 = args[0]; + if (var1.equalsIgnoreCase("config")){ + Main.getPlugin().saveDefaultConfig(); + Main.getPlugin().saveConfig(); + Main.getPlugin().reloadConfig(); + Utils.sendMessage(sender, "messages.commands.reload.config"); + return true; + } + FHologram holo = HologramsManager.getHologram(var1); + if (holo == null){ + Utils.sendMessage(sender, "messages.commands.reload.notExist"); + return true; + } + holo.reload(); + Utils.sendMessage(sender, "messages.commands.reload.success2"); + } else { + Utils.sendMessage(sender, help()); + } + return true; + } + + @Override + public List onTabComplete(CommandSender sender, String[] args) { + if (args.length == 1){ + String var1 = args[0]; + List list1 = Arrays.stream(HologramsManager.getHolograms()).map(FHologram::getName).collect(Collectors.toList()); + list1.add("config"); + List list2 = new ArrayList<>(); + + StringUtil.copyPartialMatches(var1, list1, list2); + Collections.shuffle(list2); + return list2; + } + return null; + } + + @Override + public String help() { + return Utils.getConfig().getString("messages.commands.reload.help").replace("%alias%", "fholo"); + } + + @Override + public String getPermission() { + return null; + } + + @Override + public boolean console() { + return true; + } +} diff --git a/src/main/java/me/TheJokerDev/futureholograms/commands/subcmds/RemoveCmd.java b/src/main/java/me/TheJokerDev/futureholograms/commands/subcmds/RemoveCmd.java new file mode 100644 index 0000000..59fda8b --- /dev/null +++ b/src/main/java/me/TheJokerDev/futureholograms/commands/subcmds/RemoveCmd.java @@ -0,0 +1,67 @@ +package me.TheJokerDev.futureholograms.commands.subcmds; + +import me.TheJokerDev.futureholograms.commands.SubCommand; +import me.TheJokerDev.futureholograms.holo.FHologram; +import me.TheJokerDev.futureholograms.holo.HologramsManager; +import me.TheJokerDev.futureholograms.utils.LocationUtil; +import me.TheJokerDev.futureholograms.utils.Utils; +import me.TheJokerDev.other.FileConfigurationUtil; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.util.StringUtil; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; + +public class RemoveCmd implements SubCommand { + @Override + public boolean onCommand(CommandSender sender, String[] args) { + if (args.length == 1){ + String var1 = args[0]; + FHologram var2 = HologramsManager.getHologram(var1); + if (var2 == null){ + Utils.sendMessage(sender, "messages.commands.remove.notExist"); + return true; + } + Utils.getFile("holograms.yml").set(var1, null); + var2.deleteAll(); + HologramsManager.hologramHashMap.remove(var1); + Utils.sendMessage(sender, "messages.commands.remove.success"); + } else { + Utils.sendMessage(sender, help()); + } + return true; + } + + @Override + public List onTabComplete(CommandSender sender, String[] args) { + if (args.length == 1){ + String var1 = args[0]; + List list1 = Arrays.stream(HologramsManager.getHolograms()).map(FHologram::getName).collect(Collectors.toList()); + List list2 = new ArrayList<>(); + + StringUtil.copyPartialMatches(var1, list1, list2); + Collections.shuffle(list2); + return list2; + } + return null; + } + + @Override + public String help() { + return Utils.getConfig().getString("messages.commands.remove.help").replace("%alias%", "fholo"); + } + + @Override + public String getPermission() { + return null; + } + + @Override + public boolean console() { + return false; + } +} diff --git a/src/main/java/me/TheJokerDev/futureholograms/commands/subcmds/SetExactlyLocationCmd.java b/src/main/java/me/TheJokerDev/futureholograms/commands/subcmds/SetExactlyLocationCmd.java new file mode 100644 index 0000000..038645b --- /dev/null +++ b/src/main/java/me/TheJokerDev/futureholograms/commands/subcmds/SetExactlyLocationCmd.java @@ -0,0 +1,70 @@ +package me.TheJokerDev.futureholograms.commands.subcmds; + +import me.TheJokerDev.futureholograms.commands.SubCommand; +import me.TheJokerDev.futureholograms.holo.FHologram; +import me.TheJokerDev.futureholograms.holo.HologramsManager; +import me.TheJokerDev.futureholograms.utils.Utils; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.util.StringUtil; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; + +public class SetExactlyLocationCmd implements SubCommand { + @Override + public boolean onCommand(CommandSender sender, String[] args) { + if (!(sender instanceof Player)){ + Utils.sendMessage(sender, "messages.onlyPlayers"); + return true; + } + Player p = (Player)sender; + if (args.length == 1){ + String var1 = args[0]; + FHologram var2 = HologramsManager.getHologram(var1); + if (var2 == null){ + Utils.sendMessage(sender, "messages.commands.setexactlylocation.notExist"); + return true; + } + var2.setExactlyLocation(p.getLocation()); + var2.deleteAll(); + var2.reload(); + Utils.sendMessage(sender, "messages.commands.setexactlylocation.success"); + } else { + Utils.sendMessage(sender, help()); + } + return true; + } + + @Override + public List onTabComplete(CommandSender sender, String[] args) { + if (args.length == 1){ + String var1 = args[0]; + List list1 = Arrays.stream(HologramsManager.getHolograms()).map(FHologram::getName).collect(Collectors.toList()); + List list2 = new ArrayList<>(); + + StringUtil.copyPartialMatches(var1, list1, list2); + Collections.shuffle(list2); + return list2; + } + return null; + } + + @Override + public String help() { + return Utils.getConfig().getString("messages.commands.setexactlylocation.help").replace("%alias%", "fholo"); + } + + @Override + public String getPermission() { + return null; + } + + @Override + public boolean console() { + return false; + } +} diff --git a/src/main/java/me/TheJokerDev/futureholograms/commands/subcmds/SetLocationCmd.java b/src/main/java/me/TheJokerDev/futureholograms/commands/subcmds/SetLocationCmd.java new file mode 100644 index 0000000..8a3cfd0 --- /dev/null +++ b/src/main/java/me/TheJokerDev/futureholograms/commands/subcmds/SetLocationCmd.java @@ -0,0 +1,72 @@ +package me.TheJokerDev.futureholograms.commands.subcmds; + +import me.TheJokerDev.futureholograms.commands.SubCommand; +import me.TheJokerDev.futureholograms.holo.FHologram; +import me.TheJokerDev.futureholograms.holo.HologramsManager; +import me.TheJokerDev.futureholograms.utils.LocationUtil; +import me.TheJokerDev.futureholograms.utils.Utils; +import me.TheJokerDev.other.FileConfigurationUtil; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.util.StringUtil; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; + +public class SetLocationCmd implements SubCommand { + @Override + public boolean onCommand(CommandSender sender, String[] args) { + if (!(sender instanceof Player)){ + Utils.sendMessage(sender, "messages.onlyPlayers"); + return true; + } + Player p = (Player)sender; + if (args.length == 1){ + String var1 = args[0]; + FHologram var2 = HologramsManager.getHologram(var1); + if (var2 == null){ + Utils.sendMessage(sender, "messages.commands.setlocation.notExist"); + return true; + } + var2.setLocation(p.getLocation()); + var2.deleteAll(); + var2.reload(); + Utils.sendMessage(sender, "messages.commands.setlocation.success"); + } else { + Utils.sendMessage(sender, help()); + } + return true; + } + + @Override + public List onTabComplete(CommandSender sender, String[] args) { + if (args.length == 1){ + String var1 = args[0]; + List list1 = Arrays.stream(HologramsManager.getHolograms()).map(FHologram::getName).collect(Collectors.toList()); + List list2 = new ArrayList<>(); + + StringUtil.copyPartialMatches(var1, list1, list2); + Collections.shuffle(list2); + return list2; + } + return null; + } + + @Override + public String help() { + return Utils.getConfig().getString("messages.commands.setlocation.help").replace("%alias%", "fholo"); + } + + @Override + public String getPermission() { + return null; + } + + @Override + public boolean console() { + return false; + } +} diff --git a/src/main/java/me/TheJokerDev/futureholograms/holo/FHologram.java b/src/main/java/me/TheJokerDev/futureholograms/holo/FHologram.java new file mode 100644 index 0000000..f73a669 --- /dev/null +++ b/src/main/java/me/TheJokerDev/futureholograms/holo/FHologram.java @@ -0,0 +1,384 @@ +package me.TheJokerDev.futureholograms.holo; + +import com.gmail.filoghost.holographicdisplays.api.Hologram; +import com.gmail.filoghost.holographicdisplays.api.HologramsAPI; +import com.gmail.filoghost.holographicdisplays.api.VisibilityManager; +import com.gmail.filoghost.holographicdisplays.api.handler.TouchHandler; +import com.gmail.filoghost.holographicdisplays.api.line.TextLine; +import com.gmail.filoghost.holographicdisplays.api.line.TouchableLine; +import me.TheJokerDev.futureholograms.Main; +import me.TheJokerDev.futureholograms.utils.LocationUtil; +import me.TheJokerDev.futureholograms.utils.Utils; +import me.TheJokerDev.other.XSound; +import me.clip.placeholderapi.PlaceholderAPI; +import org.apache.commons.lang.UnhandledException; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.entity.Player; +import org.bukkit.scheduler.BukkitRunnable; +import org.bukkit.scheduler.BukkitTask; + +import java.io.File; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +public class FHologram { + private final String name; + private String defaultHologram; + private BukkitTask updateTask; + private boolean refresh = false; + private int refreshRate = 20; + private Location location = null; + public HashMap holograms; + public List cooldown = new ArrayList<>(); + + public void setLocation(Location location) { + this.location = location; + Utils.getFile("holograms.yml").set(getName()+".location", LocationUtil.getString(location, true)); + Utils.getFile("holograms.yml").save(); + } + + public void setExactlyLocation(Location location) { + this.location = location; + Utils.getFile("holograms.yml").set(getName()+".location", LocationUtil.getString(location, false)); + Utils.getFile("holograms.yml").save(); + } + + public FHologram(String name){ + this.name = name; + holograms = new HashMap<>(); + defaultHologram = getSection().getString("default"); + if (getSection().get("location") != null){ + location = LocationUtil.getLocation(getSection().getString("location")); + } else { + Utils.sendMessage(Bukkit.getConsoleSender(), "{prefix}&cThe hologram "+name+" doesn't have any location to spawn!"); + return; + } + if (getSection().get("refresh") != null && getSection().getBoolean("refresh")){ + refresh = true; + } + if (getSection().get("refreshRate") != null && Utils.isNumeric(getSection().getString("refreshRate"))){ + refreshRate = getSection().getInt("refreshRate"); + } + for (Player p : Bukkit.getOnlinePlayers()){ + spawn(p); + } + + if (refresh){ + updateTask = new BukkitRunnable() { + @Override + public void run() { + if (!new File(Main.getPlugin().getDataFolder(), "holograms.yml").exists()){ + cancel(); + HologramsManager.hologramHashMap.remove(name); + deleteAll(); + return; + } + onRefresh(); + } + }.runTaskTimer(Main.getPlugin(), 0L, refreshRate); + } + } + + public void reload(){ + deleteAll(); + holograms.keySet().forEach(l->deleteHologram(l)); + holograms = new HashMap<>(); + defaultHologram = getSection().getString("default"); + if (getSection().get("location") != null){ + location = LocationUtil.getLocation(getSection().getString("location")); + } else { + Utils.sendMessage(Bukkit.getConsoleSender(), "{prefix}&cThe hologram "+name+" doesn't have any location to spawn!"); + } + if (getSection().get("refresh") != null && getSection().getBoolean("refresh")){ + refresh = true; + } + if (getSection().get("refreshRate") != null && Utils.isNumeric(getSection().getString("refreshRate"))){ + refreshRate = getSection().getInt("refreshRate"); + } + for (Player p : Bukkit.getOnlinePlayers()){ + spawn(p); + } + + if (refresh){ + updateTask = new BukkitRunnable() { + @Override + public void run() { + if (!new File(Main.getPlugin().getDataFolder(), "holograms.yml").exists()){ + cancel(); + HologramsManager.hologramHashMap.remove(name); + deleteAll(); + return; + } + onRefresh(); + } + }.runTaskTimerAsynchronously(Main.getPlugin(), 0L, refreshRate); + } + } + + public ConfigurationSection getSection(){ + return Utils.getFile("holograms.yml").getSection(name); + } + + public Hologram getHologram(Player p) { + return holograms.get(p); + } + + public void showTo(Player p, Player t){ + holograms.get(p).getVisibilityManager().showTo(t); + } + + public boolean hasCooldown(){ + return getSection().get("cooldown")!=null; + } + + public int getCooldown(){ + return getSection().getInt("cooldown"); + } + + public void hideTo(Player p, Player t){ + holograms.get(p).getVisibilityManager().showTo(t); + } + + public void deleteHologram(Player p){ + holograms.get(p).clearLines(); + holograms.get(p).delete(); + } + + public Location getLocation() { + return location; + } + + public String getFormattedLocation() { + return location != null ? "X:"+location.getBlockX()+"; Y:"+location.getBlockY()+"; Z:"+location.getBlockZ() : Utils.getConfig().getString("messages.commands.list.noLocation"); + } + + public String getSelection(Player p){ + return Utils.getFile("data.yml").getString(getName()+"."+p.getName(), defaultHologram); + } + + public void loadPlayer(Player p){ + Utils.getFile("data.yml").add(getName()+"."+p.getName(), defaultHologram); + } + + public String getName() { + return name; + } + + public void spawn(Player p){ + if (location == null){ + return; + } + Hologram holo = HologramsAPI.createHologram(Main.getPlugin(), location); + for (String s : getLines(p)){ + holo.appendTextLine(Utils.ct(PlaceholderAPI.setPlaceholders(p, s))); + } + TouchableLine lastLine = (TouchableLine) holo.getLine(getLines(p).size() - 1); + TouchHandler touchHandler = player -> { + onClick(p); + }; + holo.setAllowPlaceholders(true); + lastLine.setTouchHandler(touchHandler); + VisibilityManager var7 = holo.getVisibilityManager(); + var7.setVisibleByDefault(false); + var7.showTo(p); + holograms.put(p, holo); + } + + public void onRefresh(){ + if (holograms.isEmpty()){ + return; + } + for (Player p : getPlayers()) { + refreshPlayer(p); + } + } + + List getPlayers(){ + List p = new ArrayList<>(); + for (Player p2 : holograms.keySet()){ + if (p2!=null){ + p.add(p2); + } else { + holograms.remove(null); + } + } + + return p; + } + + public void updateTask(){ + updateTask.cancel(); + updateTask = new BukkitRunnable() { + @Override + public void run() { + if (!new File(Main.getPlugin().getDataFolder(), "holograms.yml").exists()){ + cancel(); + HologramsManager.hologramHashMap.remove(name); + deleteAll(); + return; + } + onRefresh(); + } + }.runTaskTimerAsynchronously(Main.getPlugin(), 0L, refreshRate); + } + + public void refreshPlayer(Player p){ + Hologram holo = holograms.get(p); + if (p == null || !p.isOnline()){ + holo.delete(); + holograms.remove(p); + return; + } + if (holo == null){ + holograms.remove(p); + updateTask(); + } + if (holo.isDeleted()){ + holograms.remove(p); + updateTask(); + } + final List var4 = getLines(p); + if (holo.size() > var4.size()) { + int i = holo.size() - var4.size(); + for (int i2 = 0; i2 < i; i2++) { + holo.removeLine((holo.size() - 1) - 1); + } + } + if (var4.size() < holo.size()) { + int i = holo.size() - var4.size(); + for (int i2 = 0; i2 < i; i2++) { + holo.removeLine((holo.size() - 1) - 1); + } + } else { + for (int i = 0; i < var4.size(); i++) { + if (i >= holo.size()) { + if (holo.isDeleted()){ + updateTask(); + break; + } + holo.insertTextLine(i, Utils.ct(PlaceholderAPI.setPlaceholders(p, var4.get(i)))); + continue; + } + TextLine textLine = (TextLine) holo.getLine(i); + textLine.setText(Utils.ct(PlaceholderAPI.setPlaceholders(p, var4.get(i)))); + } + } + TouchableLine lastLine; + int difference = var4.size()-holo.size(); + lastLine = (TouchableLine) holo.getLine(var4.size()-difference-1); + TouchHandler touchHandler = player -> onClick(p); + lastLine.setTouchHandler(touchHandler); + } + + public void onClick(Player p){ + if (hasCooldown()) { + if (cooldown.contains(p.getName())) { + return; + } else { + cooldown.add(p.getName()); + new BukkitRunnable() { + @Override + public void run() { + cooldown.remove(p.getName()); + } + }.runTaskLater(Main.getPlugin(), getCooldown()); + } + } + executeActions(p); + if (p.isSneaking() && hasBack(p)){ + setBack(p); + } else { + setNext(p); + } + refreshPlayer(p); + } + + private boolean hasBack(Player p){ + return getSection().get(getSelection(p)+".back")!=null; + } + + public void executeActions(Player p){ + for (String s : getActions(p)){ + boolean isCommand = s.startsWith("[command]") || s.startsWith("[console]"); + boolean isSound = s.startsWith("[sound]"); + boolean isMessage = s.startsWith("[message]"); + + if (isCommand){ + boolean isConsole = s.startsWith("[console]"); + s = s.replace("[command]", "").replace("[console]", ""); + s = PlaceholderAPI.setPlaceholders(p, s); + if (isConsole){ + Bukkit.dispatchCommand(Bukkit.getConsoleSender(), s); + } else { + p.chat("/"+s); + } + } else if (isMessage){ + s = s.replace("[message]", ""); + s = PlaceholderAPI.setPlaceholders(p, s); + Utils.sendMessage(p, s); + } else if (isSound){ + s = s.replace("[sound]", ""); + XSound sound; + float volume = 1.0F; + float pitch = 1.0F; + if (s.contains(",")){ + String[] var1 = s.split(","); + sound = XSound.valueOf(var1[0]); + volume = Float.parseFloat(var1[1]); + pitch = Float.parseFloat(var1[2]); + } else { + sound = XSound.valueOf(s.toUpperCase()); + } + sound.play(p, volume, pitch); + } + } + } + + public void deleteAll(){ + if (holograms.isEmpty()){ + return; + } + getPlayers().forEach(this::deleteHologram); + if (updateTask != null){ + updateTask.cancel(); + } + holograms.clear(); + } + + public List getLines(Player p){ + String selection = getSelection(p); + List list = new ArrayList<>(); + if (getSection().get(selection+".lines") != null){ + list.addAll(getSection().getStringList(selection+".lines")); + } + return list; + } + + public List getActions(Player p){ + String selection = getSelection(p); + List list = new ArrayList<>(); + if (getSection().get(selection+".actions") != null){ + list.addAll(getSection().getStringList(selection+".actions")); + } + return list; + } + + public void setNext(Player p){ + Utils.getFile("data.yml").set(getName()+"."+p.getName(), getNext(p)); + } + + public String getNext(Player p){ + return getSection().getString(getSelection(p)+".next", defaultHologram); + } + + public void setBack(Player p){ + Utils.getFile("data.yml").set(getName()+"."+p.getName(), getBack(p)); + } + + public String getBack(Player p){ + return getSection().getString(getSelection(p)+".back", defaultHologram); + } +} \ No newline at end of file diff --git a/src/main/java/me/TheJokerDev/futureholograms/holo/HologramsManager.java b/src/main/java/me/TheJokerDev/futureholograms/holo/HologramsManager.java new file mode 100644 index 0000000..09fcba4 --- /dev/null +++ b/src/main/java/me/TheJokerDev/futureholograms/holo/HologramsManager.java @@ -0,0 +1,38 @@ +package me.TheJokerDev.futureholograms.holo; + +import me.TheJokerDev.futureholograms.utils.Utils; +import me.TheJokerDev.other.FileConfigurationUtil; +import org.bukkit.entity.Player; + +import java.util.HashMap; + +public class HologramsManager { + public static HashMap hologramHashMap = new HashMap<>(); + + public static void initHolograms(){ + + if (!hologramHashMap.isEmpty()){ + for (FHologram hologram : hologramHashMap.values()){ + hologram.deleteAll(); + } + } + + hologramHashMap = new HashMap<>(); + + FileConfigurationUtil config = Utils.getFile("holograms.yml"); + + for (String key : config.getKeys(false)){ + FHologram hologram = new FHologram(key); + + hologramHashMap.put(key, hologram); + } + } + + public static FHologram getHologram(String s){ + return hologramHashMap.getOrDefault(s, null); + } + + public static FHologram[] getHolograms() { + return hologramHashMap.values().toArray(new FHologram[0]); + } +} diff --git a/src/main/java/me/TheJokerDev/futureholograms/listeners/LoginListeners.java b/src/main/java/me/TheJokerDev/futureholograms/listeners/LoginListeners.java new file mode 100644 index 0000000..17d1bd2 --- /dev/null +++ b/src/main/java/me/TheJokerDev/futureholograms/listeners/LoginListeners.java @@ -0,0 +1,42 @@ +package me.TheJokerDev.futureholograms.listeners; + +import me.TheJokerDev.futureholograms.holo.FHologram; +import me.TheJokerDev.futureholograms.holo.HologramsManager; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.event.player.PlayerQuitEvent; + +public class LoginListeners implements Listener { + + @EventHandler + public void onJoin(PlayerJoinEvent e){ + Player p = e.getPlayer(); + + for (FHologram holo : HologramsManager.getHolograms()) { + holo.loadPlayer(p); + if (holo.getLocation() == null){ + continue; + } + holo.spawn(p); + if (holo.getLocation().getWorld().getName().equals(p.getWorld().getName())){ + holo.showTo(p, p); + } else{ + holo.hideTo(p, p); + } + } + } + + @EventHandler + public void onLeave(PlayerQuitEvent e){ + Player p = e.getPlayer(); + + for (FHologram holo : HologramsManager.getHolograms()) { + if (holo.getLocation() == null){ + continue; + } + holo.deleteHologram(p); + } + } +} diff --git a/src/main/java/me/TheJokerDev/futureholograms/listeners/WorldListeners.java b/src/main/java/me/TheJokerDev/futureholograms/listeners/WorldListeners.java new file mode 100644 index 0000000..571e0c9 --- /dev/null +++ b/src/main/java/me/TheJokerDev/futureholograms/listeners/WorldListeners.java @@ -0,0 +1,32 @@ +package me.TheJokerDev.futureholograms.listeners; + +import me.TheJokerDev.futureholograms.holo.FHologram; +import me.TheJokerDev.futureholograms.holo.HologramsManager; +import org.bukkit.World; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerChangedWorldEvent; + +public class WorldListeners implements Listener { + + @EventHandler + public void onWorldChange (PlayerChangedWorldEvent e){ + Player p = e.getPlayer(); + World w = e.getPlayer().getWorld(); + + for (FHologram holo : HologramsManager.getHolograms()){ + if (holo.getHologram(p).isDeleted()){ + return; + } + if (holo.getHologram(p) == null){ + return; + } + if (holo.getLocation().getWorld().getName().equals(w.getName())){ + holo.showTo(p, p); + } else{ + holo.hideTo(p, p); + } + } + } +} diff --git a/src/main/java/me/TheJokerDev/futureholograms/utils/LocationUtil.java b/src/main/java/me/TheJokerDev/futureholograms/utils/LocationUtil.java new file mode 100644 index 0000000..a6675b7 --- /dev/null +++ b/src/main/java/me/TheJokerDev/futureholograms/utils/LocationUtil.java @@ -0,0 +1,53 @@ +package me.TheJokerDev.futureholograms.utils; + +import org.bukkit.Bukkit; +import org.bukkit.Location; + +import java.util.List; +import java.util.stream.Collectors; + +public class LocationUtil { + public LocationUtil() { + } + + public static Location center(Location var0) { + return new Location(var0.getWorld(), getRelativeCoord(var0.getBlockX()), getRelativeCoord(var0.getBlockY()), getRelativeCoord(var0.getBlockZ())); + } + + private static double getRelativeCoord(int var0) { + double var1 = (double)var0; + var1 = var1 < 0.0D ? var1 + 0.5D : var1 + 0.5D; + return var1; + } + + public static String getString(Location var0, boolean var1) { + if (var0 == null) { + System.out.println("Location null, can't be converted to string"); + return null; + } else { + return var1 ? var0.getWorld().getName() + "," + center(var0).getX() + "," + var0.getY() + "," + center(var0).getZ() + "," + 0 + "," + var0.getYaw() : var0.getWorld().getName() + "," + var0.getX() + "," + var0.getY() + "," + var0.getZ() + "," + var0.getPitch() + "," + var0.getYaw(); + } + } + + public static Location getLocation(String var0) { + String[] var1 = var0.split(","); + Location var2 = null; + if (var1.length < 4) { + System.out.println("Location can't be obtained from (world,x,y,z needed)'" + var0 + "'"); + } else if (var1.length < 6) { + var2 = new Location(Bukkit.getWorld(var1[0]), Double.parseDouble(var1[1]), Double.parseDouble(var1[2]), Double.parseDouble(var1[3])); + } else { + try { + var2 = new Location(Bukkit.getWorld(var1[0]), Double.parseDouble(var1[1]), Double.parseDouble(var1[2]), Double.parseDouble(var1[3]), Float.parseFloat(var1[5]), Float.parseFloat("0")); + } catch (NullPointerException var4) { + System.out.println("Location can't be obtained from '" + var0 + "'"); + } + } + + return var2; + } + + public static List getLocations(List var1){ + return var1.stream().map(LocationUtil::getLocation).collect(Collectors.toList()); + } +} diff --git a/src/main/java/me/TheJokerDev/futureholograms/utils/Utils.java b/src/main/java/me/TheJokerDev/futureholograms/utils/Utils.java new file mode 100644 index 0000000..5f1d3bd --- /dev/null +++ b/src/main/java/me/TheJokerDev/futureholograms/utils/Utils.java @@ -0,0 +1,175 @@ +package me.TheJokerDev.futureholograms.utils; + +import me.TheJokerDev.futureholograms.Main; +import me.TheJokerDev.other.DefaultFontInfo; +import me.TheJokerDev.other.FileConfigurationUtil; +import me.clip.placeholderapi.PlaceholderAPI; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import java.io.File; +import java.io.IOException; +import java.util.*; +import java.util.stream.Collectors; + +public class Utils { + + //String utils + public static String ct(String msg){ + return ChatColor.translateAlternateColorCodes('&', msg); + } + public static List ct (List list){ + return list.stream().map(Utils::ct).collect(Collectors.toList()); + } + public static String[] ct (String... list){ + return Arrays.stream(list).map(Utils::ct).toArray(String[]::new); + } + + + public static void sendMessage(CommandSender sender, List list){ + list.forEach(s->sendMessage(sender, s)); + } + public static void sendMessage(CommandSender sender, String... list){ + Arrays.stream(list).forEach(s->sendMessage(sender, s)); + } + public static void sendMessage(CommandSender sender, String path){ + String msg = null; + try { + if (getConfig().get(path)==null){ + msg = path; + } + if (msg == null) { + if (isStringList(getConfig(), path)) { + for(String s : getConfig().getStringList(path)) { + sendMessage(sender, s); + } + return; + } + if (!path.equals("")) { + msg = getConfig().getString(path); + } else { + msg = ""; + } + } + } catch (Exception e) { + msg = path; + } + msg = Utils.ct(msg); + msg = msg.replace("\\n", "\n"); + if (msg.contains("\n")){ + String[] msg2 = msg.split("\n"); + sendMessage(sender, msg2); + return; + } + boolean hasPrefix = msg.contains("{prefix}"); + boolean isCentered = msg.contains("{center}"); + boolean isBroadCast = msg.contains("{broadcast}"); + + if (hasPrefix){ + msg = msg.replace("{prefix}", ""); + msg = getPrefix()+msg; + } + if (sender instanceof Player){ + msg = PlaceholderAPI.setPlaceholders((Player)sender, msg); + } else { + msg = PlaceholderAPI.setPlaceholders(null, msg); + } + if (isCentered){ + msg = msg.replace("{center}", ""); + msg = getCenteredMSG(msg); + } + if (isBroadCast){ + msg = msg.replace("{broadcast}", ""); + String finalMsg = msg; + Bukkit.getOnlinePlayers().forEach(p -> Utils.sendMessage(p, finalMsg)); + sendMessage(Bukkit.getConsoleSender(), msg); + return; + } + + if (sender instanceof Player){ + sender.sendMessage(msg); + } else { + Bukkit.getConsoleSender().sendMessage(msg); + } + } + + public static boolean isNumeric(String var0) { + try { + Integer.parseInt(var0); + return true; + } catch (NumberFormatException var2) { + return false; + } + } + + public static String getPrefix(){ + return Main.getPrefix(); + } + + public static FileConfigurationUtil getFile(String fileName){ + File file = new File(Main.getPlugin().getDataFolder(), fileName); + + if (!file.exists()){ + try { + Main.getPlugin().saveResource(fileName, false); + } catch (Exception e) { + try { + file.createNewFile(); + } catch (IOException ignored) { + } + } + } + + return new FileConfigurationUtil(file); + } + + public static boolean isStringList(FileConfigurationUtil config, String path){ + boolean b = false; + Object var1 = config.get(path); + if (var1 instanceof List){ + b = true; + } + return b; + } + + public static FileConfigurationUtil getConfig(){ + return getFile("config.yml"); + } + + public static String getCenteredMSG(String message){ + if(message == null || message.equals("")){ + return null; + } + message = ChatColor.translateAlternateColorCodes('&', message); + + int messagePxSize = 0; + boolean previousCode = false; + boolean isBold = false; + + for(char c : message.toCharArray()){ + if(c == '§'){ + previousCode = true; + }else if(previousCode){ + previousCode = false; + isBold = c == 'l' || c == 'L'; + }else{ + DefaultFontInfo dFI = DefaultFontInfo.getDefaultFontInfo(c); + messagePxSize += isBold ? dFI.getBoldLength() : dFI.getLength(); + messagePxSize++; + } + } + + int halvedMessageSize = messagePxSize / 2; + int toCompensate = 154 - halvedMessageSize; + int spaceLength = DefaultFontInfo.SPACE.getLength() + 1; + int compensated = 0; + StringBuilder sb = new StringBuilder(); + while(compensated < toCompensate){ + sb.append(" "); + compensated += spaceLength; + } + return sb + message; + } +} diff --git a/src/main/java/me/TheJokerDev/other/DefaultFontInfo.java b/src/main/java/me/TheJokerDev/other/DefaultFontInfo.java new file mode 100644 index 0000000..72826a6 --- /dev/null +++ b/src/main/java/me/TheJokerDev/other/DefaultFontInfo.java @@ -0,0 +1,129 @@ +package me.TheJokerDev.other; + +public enum DefaultFontInfo { + + A('A', 5), + a('a', 5), + B('B', 5), + b('b', 5), + C('C', 5), + c('c', 5), + D('D', 5), + d('d', 5), + E('E', 5), + e('e', 5), + F('F', 5), + f('f', 4), + G('G', 5), + g('g', 5), + H('H', 5), + h('h', 5), + I('I', 3), + i('i', 1), + J('J', 5), + j('j', 5), + K('K', 5), + k('k', 4), + L('L', 5), + l('l', 1), + M('M', 5), + m('m', 5), + N('N', 5), + n('n', 5), + O('O', 5), + o('o', 5), + P('P', 5), + p('p', 5), + Q('Q', 5), + q('q', 5), + R('R', 5), + r('r', 5), + S('S', 5), + s('s', 5), + T('T', 5), + t('t', 4), + U('U', 5), + u('u', 5), + V('V', 5), + v('v', 5), + W('W', 5), + w('w', 5), + X('X', 5), + x('x', 5), + Y('Y', 5), + y('y', 5), + Z('Z', 5), + z('z', 5), + NUM_1('1', 5), + NUM_2('2', 5), + NUM_3('3', 5), + NUM_4('4', 5), + NUM_5('5', 5), + NUM_6('6', 5), + NUM_7('7', 5), + NUM_8('8', 5), + NUM_9('9', 5), + NUM_0('0', 5), + EXCLAMATION_POINT('!', 1), + AT_SYMBOL('@', 6), + NUM_SIGN('#', 5), + DOLLAR_SIGN('$', 5), + PERCENT('%', 5), + UP_ARROW('^', 5), + AMPERSAND('&', 5), + ASTERISK('*', 5), + LEFT_PARENTHESIS('(', 4), + RIGHT_PERENTHESIS(')', 4), + MINUS('-', 5), + UNDERSCORE('_', 5), + PLUS_SIGN('+', 5), + EQUALS_SIGN('=', 5), + LEFT_CURL_BRACE('{', 4), + RIGHT_CURL_BRACE('}', 4), + LEFT_BRACKET('[', 3), + RIGHT_BRACKET(']', 3), + COLON(':', 1), + SEMI_COLON(';', 1), + DOUBLE_QUOTE('"', 3), + SINGLE_QUOTE('\'', 1), + LEFT_ARROW('<', 4), + RIGHT_ARROW('>', 4), + QUESTION_MARK('?', 5), + SLASH('/', 5), + BACK_SLASH('\\', 5), + LINE('|', 1), + TILDE('~', 5), + TICK('`', 2), + PERIOD('.', 1), + COMMA(',', 1), + SPACE(' ', 3), + DEFAULT('a', 4); + + private char character; + private int length; + + DefaultFontInfo(char character, int length) { + this.character = character; + this.length = length; + } + + public char getCharacter(){ + return this.character; + } + + public int getLength(){ + return this.length; + } + + public int getBoldLength(){ + if(this == DefaultFontInfo.SPACE) return this.getLength(); + return this.length + 1; + } + + public static DefaultFontInfo getDefaultFontInfo(char c){ + for(DefaultFontInfo dFI : DefaultFontInfo.values()){ + if(dFI.getCharacter() == c) return dFI; + } + return DefaultFontInfo.DEFAULT; + } +} diff --git a/src/main/java/me/TheJokerDev/other/FileConfigurationUtil.java b/src/main/java/me/TheJokerDev/other/FileConfigurationUtil.java new file mode 100644 index 0000000..f612228 --- /dev/null +++ b/src/main/java/me/TheJokerDev/other/FileConfigurationUtil.java @@ -0,0 +1,322 @@ +package me.TheJokerDev.other; + +import me.TheJokerDev.futureholograms.utils.Utils; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.configuration.file.YamlConfiguration; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.nio.file.Files; +import java.util.List; +import java.util.Set; + +public class FileConfigurationUtil { + private FileConfiguration config; + private final File file; + + public FileConfigurationUtil(File file) { + this.file = file; + this.load(); + } + + public FileConfigurationUtil(File folder, String fileName) { + this(new File(folder(folder), fileName)); + } + + + public static File folder(File folder) { + if (!folder.exists()) { + folder.mkdir(); + } + + return folder; + } + public static boolean isSymlink(File file) throws IOException { + if (file == null) { + throw new NullPointerException("File must not be null"); + } else { + return Files.isSymbolicLink(file.toPath()); + } + } + public static T requireNonNull(T obj) { + if (obj == null) { + throw new NullPointerException(); + } else { + return obj; + } + } + private void load() { + try { + if (!this.file.exists()) { + this.file.createNewFile(); + } + + this.config = YamlConfiguration.loadConfiguration(this.file); + } catch (Exception var2) { + var2.printStackTrace(); + } + + } + + public void clear() { + try { + destroyFile(this.file); + if (!this.file.exists()) { + this.file.createNewFile(); + } + + this.reload(); + } catch (Exception var2) { + var2.printStackTrace(); + } + + } + + public static void cleanDirectory(File directory) throws IOException { + File[] files = verifiedListFiles(directory); + IOException exception = null; + File[] var3 = files; + int var4 = files.length; + + for(int var5 = 0; var5 < var4; ++var5) { + File file = var3[var5]; + + try { + forceDelete(file); + } catch (IOException var8) { + exception = var8; + } + } + + if (null != exception) { + throw exception; + } + } + + private static File[] verifiedListFiles(File directory) throws IOException { + String message; + if (!directory.exists()) { + message = directory + " does not exist"; + throw new IllegalArgumentException(message); + } else if (!directory.isDirectory()) { + message = directory + " is not a directory"; + throw new IllegalArgumentException(message); + } else { + File[] files = directory.listFiles(); + if (files == null) { + throw new IOException("Failed to list contents of " + directory); + } else { + return files; + } + } + } + public static void deleteDirectory(File directory) throws IOException { + if (directory.exists()) { + if (!isSymlink(directory)) { + cleanDirectory(directory); + } + + if (!directory.delete()) { + String message = "Unable to delete directory " + directory + "."; + throw new IOException(message); + } + } + } + public static void destroyFile(File file) throws Exception { + forceDelete(file); + } + public static void forceDelete(File file) throws IOException { + if (file.isDirectory()) { + deleteDirectory(file); + } else { + boolean filePresent = file.exists(); + if (!file.delete()) { + if (!filePresent) { + throw new FileNotFoundException("File does not exist: " + file); + } + + String message = "Unable to delete file: " + file; + throw new IOException(message); + } + } + + } + + public void reload() { + this.config = YamlConfiguration.loadConfiguration(this.file); + } + + public void save() { + try { + this.config.save(this.file); + } catch (Exception var2) { + var2.printStackTrace(); + } + + } + + public void set(String path, Object value) { + if (value instanceof Float) { + float val = (Float)value; + value = Float.toString(val); + } + + this.config.set(path, value); + this.save(); + } + + public void add(String path, Object value) { + if (!this.contains(path)) { + this.set(path, value); + } + + } + + public boolean contains(String path) { + return this.config.contains(path); + } + + public Object get(String path) { + return this.config.get(path); + } + + public Object get(String path, Object def) { + this.add(path, def); + return this.get(path); + } + + public String getString(String path) { + return this.config.getString(Utils.ct(path)); + } + + public String getString(String path, String def) { + this.add(path, def); + return this.getString(path); + } + + public boolean getBoolean(String path) { + return this.config.getBoolean(path); + } + + public boolean getBoolean(String path, boolean def) { + this.add(path, def); + return this.getBoolean(path); + } + + public int getInt(String path) { + return this.config.getInt(path); + } + + public int getInt(String path, int def) { + this.add(path, def); + return this.getInt(path); + } + + public double getDouble(String path) { + return this.config.getDouble(path); + } + + public double getDouble(String path, double def) { + this.add(path, def); + return this.getDouble(path); + } + + public long getLong(String path) { + return this.config.getLong(path); + } + + public long getLong(String path, long def) { + this.add(path, def); + return this.getLong(path); + } + + public float getFloat(String path) { + return (float)Long.parseLong(this.getString(path)); + } + + public float getFloat(String path, float def) { + this.add(path, def); + return this.getFloat(path); + } + + public List getList(String path) { + return this.config.getList(path); + } + + public List getList(String path, List def) { + this.add(path, def); + return this.getList(path); + } + + public List getStringList(String path) { + return this.config.getStringList(path); + } + + public List getStringList(String path, List def) { + this.add(path, def); + return this.getStringList(path); + } + + public List getBooleanList(String path) { + return this.config.getBooleanList(path); + } + + public List getBooleanList(String path, List def) { + this.add(path, def); + return this.getBooleanList(path); + } + + public List getIntList(String path) { + return this.config.getIntegerList(path); + } + + public List getIntList(String path, List def) { + this.add(path, def); + return this.getIntList(path); + } + + public List getDoubleList(String path) { + return this.config.getDoubleList(path); + } + + public List getDoubleList(String path, List def) { + this.add(path, def); + return this.getDoubleList(path); + } + + public List getLongList(String path) { + return this.config.getLongList(path); + } + + public List getLongList(String path, List def) { + this.add(path, def); + return this.getLongList(path); + } + + public List getFloatList(String path) { + return this.config.getFloatList(path); + } + + public List getFloatList(String path, List def) { + this.add(path, def); + return this.getFloatList(path); + } + + public ConfigurationSection getSection(String path) { + return this.config.getConfigurationSection(path); + } + + public Set getKeys(boolean deep) { + return this.config.getKeys(deep); + } + + public FileConfiguration getConfig() { + return this.config; + } + + public File getFile() { + return this.file; + } +} diff --git a/src/main/java/me/TheJokerDev/other/XSound.java b/src/main/java/me/TheJokerDev/other/XSound.java new file mode 100644 index 0000000..563e00a --- /dev/null +++ b/src/main/java/me/TheJokerDev/other/XSound.java @@ -0,0 +1,1504 @@ +package me.TheJokerDev.other; + + +import com.google.common.base.Enums; +import com.google.common.base.Strings; +import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang.Validate; +import org.apache.commons.lang.WordUtils; +import org.bukkit.Instrument; +import org.bukkit.Location; +import org.bukkit.Note; +import org.bukkit.Sound; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; +import org.bukkit.plugin.java.JavaPlugin; +import org.bukkit.scheduler.BukkitRunnable; +import org.bukkit.scheduler.BukkitTask; + +import java.util.*; +import java.util.concurrent.CompletableFuture; + +/** + * XSound - Universal Minecraft Sound Support
+ * 1.13 and above as priority. + *

+ * Sounds are thread-safe. But this doesn't mean you should + * use a bukkit async scheduler for every {@link Player#playSound} call. + *

+ * Volume: 0.0-∞ - 1.0f (normal) - Using higher values increase the distance from which the sound can be heard.
+ * Pitch: 0.5-2.0 - 1.0f (normal) - How fast the sound is play. + *

+ * 1.8: http://docs.codelanx.com/Bukkit/1.8/org/bukkit/Sound.html + * Latest: https://hub.spigotmc.org/javadocs/bukkit/org/bukkit/Sound.html + * Basics: https://bukkit.org/threads/151517/ + * play command: https://minecraft.gamepedia.com/Commands/play + * + * @author Crypto Morin + * @version 5.1.0.1 + * @see Sound + */ +public enum XSound { + AMBIENT_BASALT_DELTAS_ADDITIONS, + AMBIENT_BASALT_DELTAS_LOOP, + AMBIENT_BASALT_DELTAS_MOOD, + AMBIENT_CAVE("AMBIENCE_CAVE"), + AMBIENT_CRIMSON_FOREST_ADDITIONS, + AMBIENT_CRIMSON_FOREST_LOOP, + AMBIENT_CRIMSON_FOREST_MOOD, + AMBIENT_NETHER_WASTES_ADDITIONS, + AMBIENT_NETHER_WASTES_LOOP, + AMBIENT_NETHER_WASTES_MOOD, + AMBIENT_SOUL_SAND_VALLEY_ADDITIONS, + AMBIENT_SOUL_SAND_VALLEY_LOOP, + AMBIENT_SOUL_SAND_VALLEY_MOOD, + AMBIENT_UNDERWATER_ENTER, + AMBIENT_UNDERWATER_EXIT, + AMBIENT_UNDERWATER_LOOP("AMBIENT_UNDERWATER_EXIT"), + AMBIENT_UNDERWATER_LOOP_ADDITIONS("AMBIENT_UNDERWATER_EXIT"), + AMBIENT_UNDERWATER_LOOP_ADDITIONS_RARE("AMBIENT_UNDERWATER_EXIT"), + AMBIENT_UNDERWATER_LOOP_ADDITIONS_ULTRA_RARE("AMBIENT_UNDERWATER_EXIT"), + AMBIENT_WARPED_FOREST_ADDITIONS, + AMBIENT_WARPED_FOREST_LOOP, + AMBIENT_WARPED_FOREST_MOOD, + BLOCK_ANCIENT_DEBRIS_BREAK, + BLOCK_ANCIENT_DEBRIS_FALL, + BLOCK_ANCIENT_DEBRIS_HIT, + BLOCK_ANCIENT_DEBRIS_PLACE, + BLOCK_ANCIENT_DEBRIS_STEP, + BLOCK_ANVIL_BREAK("ANVIL_BREAK"), + BLOCK_ANVIL_DESTROY, + BLOCK_ANVIL_FALL, + BLOCK_ANVIL_HIT("BLOCK_ANVIL_FALL"), + BLOCK_ANVIL_LAND("ANVIL_LAND"), + BLOCK_ANVIL_PLACE("BLOCK_ANVIL_FALL"), + BLOCK_ANVIL_STEP("BLOCK_ANVIL_FALL"), + BLOCK_ANVIL_USE("ANVIL_USE"), + BLOCK_BAMBOO_BREAK, + BLOCK_BAMBOO_FALL, + BLOCK_BAMBOO_HIT, + BLOCK_BAMBOO_PLACE, + BLOCK_BAMBOO_SAPLING_BREAK, + BLOCK_BAMBOO_SAPLING_HIT, + BLOCK_BAMBOO_SAPLING_PLACE, + BLOCK_BAMBOO_STEP, + BLOCK_BARREL_CLOSE, + BLOCK_BARREL_OPEN, + BLOCK_BASALT_BREAK, + BLOCK_BASALT_FALL, + BLOCK_BASALT_HIT, + BLOCK_BASALT_PLACE, + BLOCK_BASALT_STEP, + BLOCK_BEACON_ACTIVATE, + BLOCK_BEACON_AMBIENT, + BLOCK_BEACON_DEACTIVATE("BLOCK_BEACON_AMBIENT"), + BLOCK_BEACON_POWER_SELECT("BLOCK_BEACON_AMBIENT"), + BLOCK_BEEHIVE_DRIP, + BLOCK_BEEHIVE_ENTER, + BLOCK_BEEHIVE_EXIT, + BLOCK_BEEHIVE_SHEAR, + BLOCK_BEEHIVE_WORK, + BLOCK_BELL_RESONATE, + BLOCK_BELL_USE, + BLOCK_BLASTFURNACE_FIRE_CRACKLE, + BLOCK_BONE_BLOCK_BREAK, + BLOCK_BONE_BLOCK_FALL, + BLOCK_BONE_BLOCK_HIT, + BLOCK_BONE_BLOCK_PLACE, + BLOCK_BONE_BLOCK_STEP, + BLOCK_BREWING_STAND_BREW, + BLOCK_BUBBLE_COLUMN_BUBBLE_POP, + BLOCK_BUBBLE_COLUMN_UPWARDS_AMBIENT, + BLOCK_BUBBLE_COLUMN_UPWARDS_INSIDE, + BLOCK_BUBBLE_COLUMN_WHIRLPOOL_AMBIENT, + BLOCK_BUBBLE_COLUMN_WHIRLPOOL_INSIDE, + BLOCK_CAMPFIRE_CRACKLE, + BLOCK_CHAIN_BREAK, + BLOCK_CHAIN_FALL, + BLOCK_CHAIN_HIT, + BLOCK_CHAIN_PLACE, + BLOCK_CHAIN_STEP, + BLOCK_CHEST_CLOSE("CHEST_CLOSE", "ENTITY_CHEST_CLOSE"), + BLOCK_CHEST_LOCKED, + BLOCK_CHEST_OPEN("CHEST_OPEN", "ENTITY_CHEST_OPEN"), + BLOCK_CHORUS_FLOWER_DEATH, + BLOCK_CHORUS_FLOWER_GROW, + BLOCK_COMPARATOR_CLICK, + BLOCK_COMPOSTER_EMPTY, + BLOCK_COMPOSTER_FILL, + BLOCK_COMPOSTER_FILL_SUCCESS, + BLOCK_COMPOSTER_READY, + BLOCK_CONDUIT_ACTIVATE, + BLOCK_CONDUIT_AMBIENT, + BLOCK_CONDUIT_AMBIENT_SHORT, + BLOCK_CONDUIT_ATTACK_TARGET, + BLOCK_CONDUIT_DEACTIVATE, + BLOCK_CORAL_BLOCK_BREAK, + BLOCK_CORAL_BLOCK_FALL, + BLOCK_CORAL_BLOCK_HIT, + BLOCK_CORAL_BLOCK_PLACE, + BLOCK_CORAL_BLOCK_STEP, + BLOCK_CROP_BREAK, + BLOCK_DISPENSER_DISPENSE, + BLOCK_DISPENSER_FAIL, + BLOCK_DISPENSER_LAUNCH, + BLOCK_ENCHANTMENT_TABLE_USE, + BLOCK_ENDER_CHEST_CLOSE, + BLOCK_ENDER_CHEST_OPEN, + BLOCK_END_GATEWAY_SPAWN, + BLOCK_END_PORTAL_FRAME_FILL, + BLOCK_END_PORTAL_SPAWN, + BLOCK_FENCE_GATE_CLOSE, + BLOCK_FENCE_GATE_OPEN, + BLOCK_FIRE_AMBIENT("FIRE"), + BLOCK_FIRE_EXTINGUISH("FIZZ"), + BLOCK_FUNGUS_BREAK, + BLOCK_FUNGUS_FALL, + BLOCK_FUNGUS_HIT, + BLOCK_FUNGUS_PLACE, + BLOCK_FUNGUS_STEP, + BLOCK_FURNACE_FIRE_CRACKLE, + BLOCK_GILDED_BLACKSTONE_BREAK, + BLOCK_GILDED_BLACKSTONE_FALL, + BLOCK_GILDED_BLACKSTONE_HIT, + BLOCK_GILDED_BLACKSTONE_PLACE, + BLOCK_GILDED_BLACKSTONE_STEP, + BLOCK_GLASS_BREAK("GLASS"), + BLOCK_GLASS_FALL, + BLOCK_GLASS_HIT, + BLOCK_GLASS_PLACE, + BLOCK_GLASS_STEP, + BLOCK_GRASS_BREAK("DIG_GRASS"), + BLOCK_GRASS_FALL, + BLOCK_GRASS_HIT, + BLOCK_GRASS_PLACE, + BLOCK_GRASS_STEP("STEP_GRASS"), + BLOCK_GRAVEL_BREAK("DIG_GRAVEL"), + BLOCK_GRAVEL_FALL, + BLOCK_GRAVEL_HIT, + BLOCK_GRAVEL_PLACE, + BLOCK_GRAVEL_STEP("STEP_GRAVEL"), + BLOCK_GRINDSTONE_USE, + BLOCK_HONEY_BLOCK_BREAK, + BLOCK_HONEY_BLOCK_FALL, + BLOCK_HONEY_BLOCK_HIT, + BLOCK_HONEY_BLOCK_PLACE, + BLOCK_HONEY_BLOCK_SLIDE, + BLOCK_HONEY_BLOCK_STEP, + BLOCK_IRON_DOOR_CLOSE, + BLOCK_IRON_DOOR_OPEN, + BLOCK_IRON_TRAPDOOR_CLOSE, + BLOCK_IRON_TRAPDOOR_OPEN, + BLOCK_LADDER_BREAK, + BLOCK_LADDER_FALL, + BLOCK_LADDER_HIT, + BLOCK_LADDER_PLACE, + BLOCK_LADDER_STEP("STEP_LADDER"), + BLOCK_LANTERN_BREAK, + BLOCK_LANTERN_FALL, + BLOCK_LANTERN_HIT, + BLOCK_LANTERN_PLACE, + BLOCK_LANTERN_STEP, + BLOCK_LAVA_AMBIENT("LAVA"), + BLOCK_LAVA_EXTINGUISH, + BLOCK_LAVA_POP("LAVA_POP"), + BLOCK_LEVER_CLICK, + BLOCK_LILY_PAD_PLACE("BLOCK_WATERLILY_PLACE"), + BLOCK_LODESTONE_BREAK, + BLOCK_LODESTONE_FALL, + BLOCK_LODESTONE_HIT, + BLOCK_LODESTONE_PLACE, + BLOCK_LODESTONE_STEP, + BLOCK_METAL_BREAK, + BLOCK_METAL_FALL, + BLOCK_METAL_HIT, + BLOCK_METAL_PLACE, + BLOCK_METAL_PRESSURE_PLATE_CLICK_OFF("BLOCK_METAL_PRESSUREPLATE_CLICK_OFF"), + BLOCK_METAL_PRESSURE_PLATE_CLICK_ON("BLOCK_METAL_PRESSUREPLATE_CLICK_ON"), + BLOCK_METAL_STEP, + BLOCK_NETHERITE_BLOCK_BREAK, + BLOCK_NETHERITE_BLOCK_FALL, + BLOCK_NETHERITE_BLOCK_HIT, + BLOCK_NETHERITE_BLOCK_PLACE, + BLOCK_NETHERITE_BLOCK_STEP, + BLOCK_NETHERRACK_BREAK, + BLOCK_NETHERRACK_FALL, + BLOCK_NETHERRACK_HIT, + BLOCK_NETHERRACK_PLACE, + BLOCK_NETHERRACK_STEP, + BLOCK_NETHER_BRICKS_BREAK, + BLOCK_NETHER_BRICKS_FALL, + BLOCK_NETHER_BRICKS_HIT, + BLOCK_NETHER_BRICKS_PLACE, + BLOCK_NETHER_BRICKS_STEP, + BLOCK_NETHER_GOLD_ORE_BREAK, + BLOCK_NETHER_GOLD_ORE_FALL, + BLOCK_NETHER_GOLD_ORE_HIT, + BLOCK_NETHER_GOLD_ORE_PLACE, + BLOCK_NETHER_GOLD_ORE_STEP, + BLOCK_NETHER_ORE_BREAK, + BLOCK_NETHER_ORE_FALL, + BLOCK_NETHER_ORE_HIT, + BLOCK_NETHER_ORE_PLACE, + BLOCK_NETHER_ORE_STEP, + BLOCK_NETHER_SPROUTS_BREAK, + BLOCK_NETHER_SPROUTS_FALL, + BLOCK_NETHER_SPROUTS_HIT, + BLOCK_NETHER_SPROUTS_PLACE, + BLOCK_NETHER_SPROUTS_STEP, + BLOCK_NETHER_WART_BREAK, + BLOCK_NOTE_BLOCK_BANJO, + BLOCK_NOTE_BLOCK_BASEDRUM("NOTE_BASS_DRUM", "BLOCK_NOTE_BASEDRUM"), + BLOCK_NOTE_BLOCK_BASS("NOTE_BASS", "BLOCK_NOTE_BASS"), + BLOCK_NOTE_BLOCK_BELL("BLOCK_NOTE_BELL"), + BLOCK_NOTE_BLOCK_BIT, + BLOCK_NOTE_BLOCK_CHIME("BLOCK_NOTE_CHIME"), + BLOCK_NOTE_BLOCK_COW_BELL, + BLOCK_NOTE_BLOCK_DIDGERIDOO, + BLOCK_NOTE_BLOCK_FLUTE("BLOCK_NOTE_FLUTE"), + BLOCK_NOTE_BLOCK_GUITAR("NOTE_BASS_GUITAR", "BLOCK_NOTE_GUITAR"), + BLOCK_NOTE_BLOCK_HARP("NOTE_PIANO", "BLOCK_NOTE_HARP"), + BLOCK_NOTE_BLOCK_HAT("NOTE_STICKS", "BLOCK_NOTE_HAT"), + BLOCK_NOTE_BLOCK_IRON_XYLOPHONE, + BLOCK_NOTE_BLOCK_PLING("NOTE_PLING", "BLOCK_NOTE_PLING"), + BLOCK_NOTE_BLOCK_SNARE("NOTE_SNARE_DRUM", "BLOCK_NOTE_SNARE"), + BLOCK_NOTE_BLOCK_XYLOPHONE("BLOCK_NOTE_XYLOPHONE"), + BLOCK_NYLIUM_BREAK, + BLOCK_NYLIUM_FALL, + BLOCK_NYLIUM_HIT, + BLOCK_NYLIUM_PLACE, + BLOCK_NYLIUM_STEP, + BLOCK_PISTON_CONTRACT("PISTON_RETRACT"), + BLOCK_PISTON_EXTEND("PISTON_EXTEND"), + BLOCK_PORTAL_AMBIENT("PORTAL"), + BLOCK_PORTAL_TRAVEL("PORTAL_TRAVEL"), + BLOCK_PORTAL_TRIGGER("PORTAL_TRIGGER"), + BLOCK_PUMPKIN_CARVE, + BLOCK_REDSTONE_TORCH_BURNOUT, + BLOCK_RESPAWN_ANCHOR_AMBIENT, + BLOCK_RESPAWN_ANCHOR_CHARGE, + BLOCK_RESPAWN_ANCHOR_DEPLETE, + BLOCK_RESPAWN_ANCHOR_SET_SPAWN, + BLOCK_ROOTS_BREAK, + BLOCK_ROOTS_FALL, + BLOCK_ROOTS_HIT, + BLOCK_ROOTS_PLACE, + BLOCK_ROOTS_STEP, + BLOCK_SAND_BREAK("DIG_SAND"), + BLOCK_SAND_FALL, + BLOCK_SAND_HIT, + BLOCK_SAND_PLACE, + BLOCK_SAND_STEP("STEP_SAND"), + BLOCK_SCAFFOLDING_BREAK, + BLOCK_SCAFFOLDING_FALL, + BLOCK_SCAFFOLDING_HIT, + BLOCK_SCAFFOLDING_PLACE, + BLOCK_SCAFFOLDING_STEP, + BLOCK_SHROOMLIGHT_BREAK, + BLOCK_SHROOMLIGHT_FALL, + BLOCK_SHROOMLIGHT_HIT, + BLOCK_SHROOMLIGHT_PLACE, + BLOCK_SHROOMLIGHT_STEP, + BLOCK_SHULKER_BOX_CLOSE, + BLOCK_SHULKER_BOX_OPEN, + BLOCK_SLIME_BLOCK_BREAK("BLOCK_SLIME_BREAK"), + BLOCK_SLIME_BLOCK_FALL("BLOCK_SLIME_FALL"), + BLOCK_SLIME_BLOCK_HIT("BLOCK_SLIME_HIT"), + BLOCK_SLIME_BLOCK_PLACE("BLOCK_SLIME_PLACE"), + BLOCK_SLIME_BLOCK_STEP("BLOCK_SLIME_STEP"), + BLOCK_SMITHING_TABLE_USE, + BLOCK_SMOKER_SMOKE, + BLOCK_SNOW_BREAK("DIG_SNOW"), + BLOCK_SNOW_FALL, + BLOCK_SNOW_HIT, + BLOCK_SNOW_PLACE, + BLOCK_SNOW_STEP("STEP_SNOW"), + BLOCK_SOUL_SAND_BREAK, + BLOCK_SOUL_SAND_FALL, + BLOCK_SOUL_SAND_HIT, + BLOCK_SOUL_SAND_PLACE, + BLOCK_SOUL_SAND_STEP, + BLOCK_SOUL_SOIL_BREAK, + BLOCK_SOUL_SOIL_FALL, + BLOCK_SOUL_SOIL_HIT, + BLOCK_SOUL_SOIL_PLACE, + BLOCK_SOUL_SOIL_STEP, + BLOCK_STEM_BREAK, + BLOCK_STEM_FALL, + BLOCK_STEM_HIT, + BLOCK_STEM_PLACE, + BLOCK_STEM_STEP, + BLOCK_STONE_BREAK("DIG_STONE"), + BLOCK_STONE_BUTTON_CLICK_OFF, + BLOCK_STONE_BUTTON_CLICK_ON, + BLOCK_STONE_FALL, + BLOCK_STONE_HIT, + BLOCK_STONE_PLACE, + BLOCK_STONE_PRESSURE_PLATE_CLICK_OFF("BLOCK_STONE_PRESSUREPLATE_CLICK_OFF"), + BLOCK_STONE_PRESSURE_PLATE_CLICK_ON("BLOCK_STONE_PRESSUREPLATE_CLICK_ON"), + BLOCK_STONE_STEP("STEP_STONE"), + BLOCK_SWEET_BERRY_BUSH_BREAK, + BLOCK_SWEET_BERRY_BUSH_PLACE, + BLOCK_TRIPWIRE_ATTACH, + BLOCK_TRIPWIRE_CLICK_OFF, + BLOCK_TRIPWIRE_CLICK_ON, + BLOCK_TRIPWIRE_DETACH, + BLOCK_VINE_STEP, + BLOCK_WART_BLOCK_BREAK, + BLOCK_WART_BLOCK_FALL, + BLOCK_WART_BLOCK_HIT, + BLOCK_WART_BLOCK_PLACE, + BLOCK_WART_BLOCK_STEP, + BLOCK_WATER_AMBIENT("WATER"), + BLOCK_WEEPING_VINES_BREAK, + BLOCK_WEEPING_VINES_FALL, + BLOCK_WEEPING_VINES_HIT, + BLOCK_WEEPING_VINES_PLACE, + BLOCK_WEEPING_VINES_STEP, + BLOCK_WET_GRASS_BREAK, + BLOCK_WET_GRASS_FALL, + BLOCK_WET_GRASS_HIT, + BLOCK_WET_GRASS_PLACE("BLOCK_WET_GRASS_HIT"), + BLOCK_WET_GRASS_STEP("BLOCK_WET_GRASS_HIT"), + BLOCK_WOODEN_BUTTON_CLICK_OFF("WOOD_CLICK", "BLOCK_WOOD_BUTTON_CLICK_OFF"), + BLOCK_WOODEN_BUTTON_CLICK_ON("WOOD_CLICK", "BLOCK_WOOD_BUTTON_CLICK_ON"), + BLOCK_WOODEN_DOOR_CLOSE("DOOR_CLOSE"), + BLOCK_WOODEN_DOOR_OPEN("DOOR_OPEN"), + BLOCK_WOODEN_PRESSURE_PLATE_CLICK_OFF("BLOCK_WOOD_PRESSUREPLATE_CLICK_OFF"), + BLOCK_WOODEN_PRESSURE_PLATE_CLICK_ON("BLOCK_WOOD_PRESSUREPLATE_CLICK_ON"), + BLOCK_WOODEN_TRAPDOOR_CLOSE, + BLOCK_WOODEN_TRAPDOOR_OPEN, + BLOCK_WOOD_BREAK("DIG_WOOD"), + BLOCK_WOOD_FALL, + BLOCK_WOOD_HIT, + BLOCK_WOOD_PLACE, + BLOCK_WOOD_STEP("STEP_WOOD"), + BLOCK_WOOL_BREAK("DIG_WOOL", "BLOCK_CLOTH_BREAK"), + BLOCK_WOOL_FALL, + BLOCK_WOOL_HIT("BLOCK_WOOL_FALL"), + BLOCK_WOOL_PLACE("BLOCK_WOOL_FALL"), + BLOCK_WOOL_STEP("STEP_WOOL", "BLOCK_CLOTH_STEP"), + ENCHANT_THORNS_HIT, + ENTITY_ARMOR_STAND_BREAK("ENTITY_ARMORSTAND_BREAK"), + ENTITY_ARMOR_STAND_FALL("ENTITY_ARMORSTAND_FALL"), + ENTITY_ARMOR_STAND_HIT("ENTITY_ARMORSTAND_HIT"), + ENTITY_ARMOR_STAND_PLACE("ENTITY_ARMORSTAND_PLACE"), + ENTITY_ARROW_HIT("ARROW_HIT"), + ENTITY_ARROW_HIT_PLAYER("SUCCESSFUL_HIT"), + ENTITY_ARROW_SHOOT("SHOOT_ARROW"), + ENTITY_BAT_AMBIENT("BAT_IDLE"), + ENTITY_BAT_DEATH("BAT_DEATH"), + ENTITY_BAT_HURT("BAT_HURT"), + ENTITY_BAT_LOOP("BAT_LOOP"), + ENTITY_BAT_TAKEOFF("BAT_TAKEOFF"), + ENTITY_BEE_DEATH, + ENTITY_BEE_HURT, + ENTITY_BEE_LOOP, + ENTITY_BEE_LOOP_AGGRESSIVE, + ENTITY_BEE_POLLINATE, + ENTITY_BEE_STING, + ENTITY_BLAZE_AMBIENT("BLAZE_BREATH"), + ENTITY_BLAZE_BURN, + ENTITY_BLAZE_DEATH("BLAZE_DEATH"), + ENTITY_BLAZE_HURT("BLAZE_HIT"), + ENTITY_BLAZE_SHOOT, + ENTITY_BOAT_PADDLE_LAND, + ENTITY_BOAT_PADDLE_WATER, + ENTITY_CAT_AMBIENT("CAT_MEOW"), + ENTITY_CAT_BEG_FOR_FOOD, + ENTITY_CAT_DEATH, + ENTITY_CAT_EAT, + ENTITY_CAT_HISS("CAT_HISS"), + ENTITY_CAT_HURT("CAT_HIT"), + ENTITY_CAT_PURR("CAT_PURR"), + ENTITY_CAT_PURREOW("CAT_PURREOW"), + ENTITY_CAT_STRAY_AMBIENT, + ENTITY_CHICKEN_AMBIENT("CHICKEN_IDLE"), + ENTITY_CHICKEN_DEATH, + ENTITY_CHICKEN_EGG("CHICKEN_EGG_POP"), + ENTITY_CHICKEN_HURT("CHICKEN_HURT"), + ENTITY_CHICKEN_STEP("CHICKEN_WALK"), + ENTITY_COD_AMBIENT, + ENTITY_COD_DEATH, + ENTITY_COD_FLOP, + ENTITY_COD_HURT, + ENTITY_COW_AMBIENT("COW_IDLE"), + ENTITY_COW_DEATH, + ENTITY_COW_HURT("COW_HURT"), + ENTITY_COW_MILK, + ENTITY_COW_STEP("COW_WALK"), + ENTITY_CREEPER_DEATH("CREEPER_DEATH"), + ENTITY_CREEPER_HURT, + ENTITY_CREEPER_PRIMED("CREEPER_HISS"), + ENTITY_DOLPHIN_AMBIENT, + ENTITY_DOLPHIN_AMBIENT_WATER, + ENTITY_DOLPHIN_ATTACK, + ENTITY_DOLPHIN_DEATH, + ENTITY_DOLPHIN_EAT, + ENTITY_DOLPHIN_HURT, + ENTITY_DOLPHIN_JUMP, + ENTITY_DOLPHIN_PLAY, + ENTITY_DOLPHIN_SPLASH, + ENTITY_DOLPHIN_SWIM, + ENTITY_DONKEY_AMBIENT("DONKEY_IDLE"), + ENTITY_DONKEY_ANGRY("DONKEY_ANGRY"), + ENTITY_DONKEY_CHEST, + ENTITY_DONKEY_DEATH("DONKEY_DEATH"), + ENTITY_DONKEY_EAT, + ENTITY_DONKEY_HURT("DONKEY_HIT"), + ENTITY_DRAGON_FIREBALL_EXPLODE("ENTITY_ENDERDRAGON_FIREBALL_EXPLODE"), + ENTITY_DROWNED_AMBIENT, + ENTITY_DROWNED_AMBIENT_WATER, + ENTITY_DROWNED_DEATH, + ENTITY_DROWNED_DEATH_WATER, + ENTITY_DROWNED_HURT, + ENTITY_DROWNED_HURT_WATER, + ENTITY_DROWNED_SHOOT, + ENTITY_DROWNED_STEP, + ENTITY_DROWNED_SWIM, + ENTITY_EGG_THROW, + ENTITY_ELDER_GUARDIAN_AMBIENT, + ENTITY_ELDER_GUARDIAN_AMBIENT_LAND, + ENTITY_ELDER_GUARDIAN_CURSE, + ENTITY_ELDER_GUARDIAN_DEATH, + ENTITY_ELDER_GUARDIAN_DEATH_LAND, + ENTITY_ELDER_GUARDIAN_FLOP, + ENTITY_ELDER_GUARDIAN_HURT, + ENTITY_ELDER_GUARDIAN_HURT_LAND, + ENTITY_ENDERMAN_AMBIENT("ENDERMAN_IDLE", "ENTITY_ENDERMEN_AMBIENT"), + ENTITY_ENDERMAN_DEATH("ENDERMAN_DEATH", "ENTITY_ENDERMEN_DEATH"), + ENTITY_ENDERMAN_HURT("ENDERMAN_HIT", "ENTITY_ENDERMEN_HURT"), + ENTITY_ENDERMAN_SCREAM("ENDERMAN_SCREAM", "ENTITY_ENDERMEN_SCREAM"), + ENTITY_ENDERMAN_STARE("ENDERMAN_STARE", "ENTITY_ENDERMEN_STARE"), + ENTITY_ENDERMAN_TELEPORT("ENDERMAN_TELEPORT", "ENTITY_ENDERMEN_TELEPORT"), + ENTITY_ENDERMITE_AMBIENT, + ENTITY_ENDERMITE_DEATH, + ENTITY_ENDERMITE_HURT, + ENTITY_ENDERMITE_STEP, + ENTITY_ENDER_DRAGON_AMBIENT("ENDERDRAGON_WINGS", "ENTITY_ENDERDRAGON_AMBIENT"), + ENTITY_ENDER_DRAGON_DEATH("ENDERDRAGON_DEATH", "ENTITY_ENDERDRAGON_DEATH"), + ENTITY_ENDER_DRAGON_FLAP("ENDERDRAGON_WINGS", "ENTITY_ENDERDRAGON_FLAP"), + ENTITY_ENDER_DRAGON_GROWL("ENDERDRAGON_GROWL", "ENTITY_ENDERDRAGON_GROWL"), + ENTITY_ENDER_DRAGON_HURT("ENDERDRAGON_HIT", "ENTITY_ENDERDRAGON_HURT"), + ENTITY_ENDER_DRAGON_SHOOT("ENTITY_ENDERDRAGON_SHOOT"), + ENTITY_ENDER_EYE_DEATH, + ENTITY_ENDER_EYE_LAUNCH("ENTITY_ENDER_EYE_DEATH", "ENTITY_ENDEREYE_DEATH"), + ENTITY_ENDER_PEARL_THROW("ENTITY_ENDERPEARL_THROW"), + ENTITY_EVOKER_AMBIENT("ENTITY_EVOCATION_ILLAGER_AMBIENT"), + ENTITY_EVOKER_CAST_SPELL("ENTITY_EVOCATION_ILLAGER_CAST_SPELL"), + ENTITY_EVOKER_CELEBRATE, + ENTITY_EVOKER_DEATH("ENTITY_EVOCATION_ILLAGER_DEATH"), + ENTITY_EVOKER_FANGS_ATTACK("ENTITY_EVOCATION_FANGS_ATTACK"), + ENTITY_EVOKER_HURT("ENTITY_EVOCATION_ILLAGER_HURT"), + ENTITY_EVOKER_PREPARE_ATTACK("ENTITY_EVOCATION_ILLAGER_PREPARE_ATTACK"), + ENTITY_EVOKER_PREPARE_SUMMON("ENTITY_EVOCATION_ILLAGER_PREPARE_SUMMON"), + ENTITY_EVOKER_PREPARE_WOLOLO("ENTITY_EVOCATION_ILLAGER_PREPARE_WOLOLO"), + ENTITY_EXPERIENCE_BOTTLE_THROW, + ENTITY_EXPERIENCE_ORB_PICKUP("ORB_PICKUP"), + ENTITY_FIREWORK_ROCKET_BLAST("FIREWORK_BLAST", "ENTITY_FIREWORK_BLAST"), + ENTITY_FIREWORK_ROCKET_BLAST_FAR("FIREWORK_BLAST2", "ENTITY_FIREWORK_BLAST_FAR"), + ENTITY_FIREWORK_ROCKET_LARGE_BLAST("FIREWORK_LARGE_BLAST", "ENTITY_FIREWORK_LARGE_BLAST"), + ENTITY_FIREWORK_ROCKET_LARGE_BLAST_FAR("FIREWORK_LARGE_BLAST2", "ENTITY_FIREWORK_LARGE_BLAST_FAR"), + ENTITY_FIREWORK_ROCKET_LAUNCH("FIREWORK_LAUNCH", "ENTITY_FIREWORK_LAUNCH"), + ENTITY_FIREWORK_ROCKET_SHOOT, + ENTITY_FIREWORK_ROCKET_TWINKLE("FIREWORK_TWINKLE", "ENTITY_FIREWORK_TWINKLE"), + ENTITY_FIREWORK_ROCKET_TWINKLE_FAR("FIREWORK_TWINKLE2", "ENTITY_FIREWORK_TWINKLE_FAR"), + ENTITY_FISHING_BOBBER_RETRIEVE, + ENTITY_FISHING_BOBBER_SPLASH("SPLASH2", "ENTITY_BOBBER_SPLASH"), + ENTITY_FISHING_BOBBER_THROW("ENTITY_BOBBER_THROW"), + ENTITY_FISH_SWIM, + ENTITY_FOX_AGGRO, + ENTITY_FOX_AMBIENT, + ENTITY_FOX_BITE, + ENTITY_FOX_DEATH, + ENTITY_FOX_EAT, + ENTITY_FOX_HURT, + ENTITY_FOX_SCREECH, + ENTITY_FOX_SLEEP, + ENTITY_FOX_SNIFF, + ENTITY_FOX_SPIT, + ENTITY_FOX_TELEPORT, + ENTITY_GENERIC_BIG_FALL("FALL_BIG"), + ENTITY_GENERIC_BURN, + ENTITY_GENERIC_DEATH, + ENTITY_GENERIC_DRINK("DRINK"), + ENTITY_GENERIC_EAT("EAT"), + ENTITY_GENERIC_EXPLODE("EXPLODE"), + ENTITY_GENERIC_EXTINGUISH_FIRE, + ENTITY_GENERIC_HURT, + ENTITY_GENERIC_SMALL_FALL("FALL_SMALL"), + ENTITY_GENERIC_SPLASH("SPLASH"), + ENTITY_GENERIC_SWIM("SWIM"), + ENTITY_GHAST_AMBIENT("GHAST_MOAN"), + ENTITY_GHAST_DEATH("GHAST_DEATH"), + ENTITY_GHAST_HURT("GHAST_SCREAM2"), + ENTITY_GHAST_SCREAM("GHAST_SCREAM"), + ENTITY_GHAST_SHOOT("GHAST_FIREBALL"), + ENTITY_GHAST_WARN("GHAST_CHARGE"), + ENTITY_GUARDIAN_AMBIENT, + ENTITY_GUARDIAN_AMBIENT_LAND, + ENTITY_GUARDIAN_ATTACK, + ENTITY_GUARDIAN_DEATH, + ENTITY_GUARDIAN_DEATH_LAND, + ENTITY_GUARDIAN_FLOP, + ENTITY_GUARDIAN_HURT, + ENTITY_GUARDIAN_HURT_LAND, + ENTITY_HOGLIN_AMBIENT, + ENTITY_HOGLIN_ANGRY, + ENTITY_HOGLIN_ATTACK, + ENTITY_HOGLIN_CONVERTED_TO_ZOMBIFIED, + ENTITY_HOGLIN_DEATH, + ENTITY_HOGLIN_HURT, + ENTITY_HOGLIN_RETREAT, + ENTITY_HOGLIN_STEP, + ENTITY_HORSE_AMBIENT("HORSE_IDLE"), + ENTITY_HORSE_ANGRY("HORSE_ANGRY"), + ENTITY_HORSE_ARMOR("HORSE_ARMOR"), + ENTITY_HORSE_BREATHE("HORSE_BREATHE"), + ENTITY_HORSE_DEATH("HORSE_DEATH"), + ENTITY_HORSE_EAT, + ENTITY_HORSE_GALLOP("HORSE_GALLOP"), + ENTITY_HORSE_HURT("HORSE_HIT"), + ENTITY_HORSE_JUMP("HORSE_JUMP"), + ENTITY_HORSE_LAND("HORSE_LAND"), + ENTITY_HORSE_SADDLE("HORSE_SADDLE"), + ENTITY_HORSE_STEP("HORSE_SOFT"), + ENTITY_HORSE_STEP_WOOD("HORSE_WOOD"), + ENTITY_HOSTILE_BIG_FALL("FALL_BIG"), + ENTITY_HOSTILE_DEATH, + ENTITY_HOSTILE_HURT, + ENTITY_HOSTILE_SMALL_FALL("FALL_SMALL"), + ENTITY_HOSTILE_SPLASH("SPLASH"), + ENTITY_HOSTILE_SWIM("SWIM"), + ENTITY_HUSK_AMBIENT, + ENTITY_HUSK_CONVERTED_TO_ZOMBIE, + ENTITY_HUSK_DEATH, + ENTITY_HUSK_HURT, + ENTITY_HUSK_STEP, + ENTITY_ILLUSIONER_AMBIENT("ENTITY_ILLUSION_ILLAGER_AMBIENT"), + ENTITY_ILLUSIONER_CAST_SPELL("ENTITY_ILLUSION_ILLAGER_CAST_SPELL"), + ENTITY_ILLUSIONER_DEATH("ENTITY_ILLUSIONER_CAST_DEATH", "ENTITY_ILLUSION_ILLAGER_DEATH"), + ENTITY_ILLUSIONER_HURT("ENTITY_ILLUSION_ILLAGER_HURT"), + ENTITY_ILLUSIONER_MIRROR_MOVE("ENTITY_ILLUSION_ILLAGER_MIRROR_MOVE"), + ENTITY_ILLUSIONER_PREPARE_BLINDNESS("ENTITY_ILLUSION_ILLAGER_PREPARE_BLINDNESS"), + ENTITY_ILLUSIONER_PREPARE_MIRROR("ENTITY_ILLUSION_ILLAGER_PREPARE_MIRROR"), + ENTITY_IRON_GOLEM_ATTACK("IRONGOLEM_THROW", "ENTITY_IRONGOLEM_ATTACK"), + ENTITY_IRON_GOLEM_DAMAGE, + ENTITY_IRON_GOLEM_DEATH("IRONGOLEM_DEATH", "ENTITY_IRONGOLEM_DEATH"), + ENTITY_IRON_GOLEM_HURT("IRONGOLEM_HIT", "ENTITY_IRONGOLEM_HURT"), + ENTITY_IRON_GOLEM_REPAIR, + ENTITY_IRON_GOLEM_STEP("IRONGOLEM_WALK", "ENTITY_IRONGOLEM_STEP"), + ENTITY_ITEM_BREAK("ITEM_BREAK"), + ENTITY_ITEM_FRAME_ADD_ITEM("ENTITY_ITEMFRAME_ADD_ITEM"), + ENTITY_ITEM_FRAME_BREAK("ENTITY_ITEMFRAME_BREAK"), + ENTITY_ITEM_FRAME_PLACE("ENTITY_ITEMFRAME_PLACE"), + ENTITY_ITEM_FRAME_REMOVE_ITEM("ENTITY_ITEMFRAME_REMOVE_ITEM"), + ENTITY_ITEM_FRAME_ROTATE_ITEM("ENTITY_ITEMFRAME_ROTATE_ITEM"), + ENTITY_ITEM_PICKUP("ITEM_PICKUP"), + ENTITY_LEASH_KNOT_BREAK("ENTITY_LEASHKNOT_BREAK"), + ENTITY_LEASH_KNOT_PLACE("ENTITY_LEASHKNOT_PLACE"), + ENTITY_LIGHTNING_BOLT_IMPACT("AMBIENCE_THUNDER", "ENTITY_LIGHTNING_IMPACT"), + ENTITY_LIGHTNING_BOLT_THUNDER("AMBIENCE_THUNDER", "ENTITY_LIGHTNING_THUNDER"), + ENTITY_LINGERING_POTION_THROW, + ENTITY_LLAMA_AMBIENT, + ENTITY_LLAMA_ANGRY, + ENTITY_LLAMA_CHEST, + ENTITY_LLAMA_DEATH, + ENTITY_LLAMA_EAT, + ENTITY_LLAMA_HURT, + ENTITY_LLAMA_SPIT, + ENTITY_LLAMA_STEP, + ENTITY_LLAMA_SWAG, + ENTITY_MAGMA_CUBE_DEATH("ENTITY_MAGMACUBE_DEATH"), + ENTITY_MAGMA_CUBE_DEATH_SMALL("ENTITY_SMALL_MAGMACUBE_DEATH"), + ENTITY_MAGMA_CUBE_HURT("ENTITY_MAGMACUBE_HURT"), + ENTITY_MAGMA_CUBE_HURT_SMALL("ENTITY_SMALL_MAGMACUBE_HURT"), + ENTITY_MAGMA_CUBE_JUMP("MAGMACUBE_JUMP", "ENTITY_MAGMACUBE_JUMP"), + ENTITY_MAGMA_CUBE_SQUISH("MAGMACUBE_WALK", "ENTITY_MAGMACUBE_SQUISH"), + ENTITY_MAGMA_CUBE_SQUISH_SMALL("MAGMACUBE_WALK2", "ENTITY_SMALL_MAGMACUBE_SQUISH"), + ENTITY_MINECART_INSIDE("MINECART_INSIDE"), + ENTITY_MINECART_RIDING("MINECART_BASE"), + ENTITY_MOOSHROOM_CONVERT, + ENTITY_MOOSHROOM_EAT, + ENTITY_MOOSHROOM_MILK, + ENTITY_MOOSHROOM_SHEAR, + ENTITY_MOOSHROOM_SUSPICIOUS_MILK, + ENTITY_MULE_AMBIENT, + ENTITY_MULE_ANGRY, + ENTITY_MULE_CHEST("ENTITY_MULE_AMBIENT"), + ENTITY_MULE_DEATH("ENTITY_MULE_AMBIENT"), + ENTITY_MULE_EAT, + ENTITY_MULE_HURT("ENTITY_MULE_AMBIENT"), + ENTITY_OCELOT_AMBIENT, + ENTITY_OCELOT_DEATH, + ENTITY_OCELOT_HURT, + ENTITY_PAINTING_BREAK, + ENTITY_PAINTING_PLACE, + ENTITY_PANDA_AGGRESSIVE_AMBIENT, + ENTITY_PANDA_AMBIENT, + ENTITY_PANDA_BITE, + ENTITY_PANDA_CANT_BREED, + ENTITY_PANDA_DEATH, + ENTITY_PANDA_EAT, + ENTITY_PANDA_HURT, + ENTITY_PANDA_PRE_SNEEZE, + ENTITY_PANDA_SNEEZE, + ENTITY_PANDA_STEP, + ENTITY_PANDA_WORRIED_AMBIENT, + ENTITY_PARROT_AMBIENT, + ENTITY_PARROT_DEATH, + ENTITY_PARROT_EAT, + ENTITY_PARROT_FLY, + ENTITY_PARROT_HURT, + ENTITY_PARROT_IMITATE_BLAZE, + ENTITY_PARROT_IMITATE_CREEPER, + ENTITY_PARROT_IMITATE_DROWNED, + ENTITY_PARROT_IMITATE_ELDER_GUARDIAN, + /** + * Removed in 1.15 + */ + ENTITY_PARROT_IMITATE_ENDERMAN, + ENTITY_PARROT_IMITATE_ENDERMITE, + ENTITY_PARROT_IMITATE_ENDER_DRAGON, + ENTITY_PARROT_IMITATE_EVOKER, + ENTITY_PARROT_IMITATE_GHAST, + ENTITY_PARROT_IMITATE_GUARDIAN, + ENTITY_PARROT_IMITATE_HOGLIN, + ENTITY_PARROT_IMITATE_HUSK, + ENTITY_PARROT_IMITATE_ILLUSIONER, + ENTITY_PARROT_IMITATE_MAGMA_CUBE, + ENTITY_PARROT_IMITATE_PHANTOM, + ENTITY_PARROT_IMITATE_PIGLIN, + ENTITY_PARROT_IMITATE_PILLAGER, + /** + * Removed in 1.15 + */ + ENTITY_PARROT_IMITATE_POLAR_BEAR, + ENTITY_PARROT_IMITATE_RAVAGER, + ENTITY_PARROT_IMITATE_SHULKER, + ENTITY_PARROT_IMITATE_SILVERFISH, + ENTITY_PARROT_IMITATE_SKELETON, + ENTITY_PARROT_IMITATE_SLIME, + ENTITY_PARROT_IMITATE_SPIDER, + ENTITY_PARROT_IMITATE_STRAY, + ENTITY_PARROT_IMITATE_VEX, + ENTITY_PARROT_IMITATE_VINDICATOR, + ENTITY_PARROT_IMITATE_WITCH, + ENTITY_PARROT_IMITATE_WITHER, + ENTITY_PARROT_IMITATE_WITHER_SKELETON, + /** + * Removed in 1.15 + */ + ENTITY_PARROT_IMITATE_WOLF, + ENTITY_PARROT_IMITATE_ZOGLIN, + ENTITY_PARROT_IMITATE_ZOMBIE, + ENTITY_PARROT_IMITATE_ZOMBIE_VILLAGER, + ENTITY_PARROT_STEP, + ENTITY_PHANTOM_AMBIENT, + ENTITY_PHANTOM_BITE, + ENTITY_PHANTOM_DEATH, + ENTITY_PHANTOM_FLAP, + ENTITY_PHANTOM_HURT, + ENTITY_PHANTOM_SWOOP, + ENTITY_PIGLIN_ADMIRING_ITEM, + ENTITY_PIGLIN_AMBIENT, + ENTITY_PIGLIN_ANGRY, + ENTITY_PIGLIN_CELEBRATE, + ENTITY_PIGLIN_CONVERTED_TO_ZOMBIFIED, + ENTITY_PIGLIN_DEATH, + ENTITY_PIGLIN_HURT, + ENTITY_PIGLIN_JEALOUS, + ENTITY_PIGLIN_RETREAT, + ENTITY_PIGLIN_STEP, + ENTITY_PIG_AMBIENT("PIG_IDLE"), + ENTITY_PIG_DEATH("PIG_DEATH"), + ENTITY_PIG_HURT, + ENTITY_PIG_SADDLE("ENTITY_PIG_HURT"), + ENTITY_PIG_STEP("PIG_WALK"), + ENTITY_PILLAGER_AMBIENT, + ENTITY_PILLAGER_CELEBRATE, + ENTITY_PILLAGER_DEATH, + ENTITY_PILLAGER_HURT, + ENTITY_PLAYER_ATTACK_CRIT, + ENTITY_PLAYER_ATTACK_KNOCKBACK, + ENTITY_PLAYER_ATTACK_NODAMAGE, + ENTITY_PLAYER_ATTACK_STRONG("SUCCESSFUL_HIT"), + ENTITY_PLAYER_ATTACK_SWEEP, + ENTITY_PLAYER_ATTACK_WEAK, + ENTITY_PLAYER_BIG_FALL("FALL_BIG"), + ENTITY_PLAYER_BREATH, + ENTITY_PLAYER_BURP("BURP"), + ENTITY_PLAYER_DEATH, + ENTITY_PLAYER_HURT("HURT_FLESH"), + ENTITY_PLAYER_HURT_DROWN, + ENTITY_PLAYER_HURT_ON_FIRE, + ENTITY_PLAYER_HURT_SWEET_BERRY_BUSH, + ENTITY_PLAYER_LEVELUP("LEVEL_UP"), + ENTITY_PLAYER_SMALL_FALL("FALL_SMALL"), + ENTITY_PLAYER_SPLASH("SLASH"), + ENTITY_PLAYER_SPLASH_HIGH_SPEED("SPLASH"), + ENTITY_PLAYER_SWIM("SWIM"), + ENTITY_POLAR_BEAR_AMBIENT, + ENTITY_POLAR_BEAR_AMBIENT_BABY("ENTITY_POLAR_BEAR_BABY_AMBIENT"), + ENTITY_POLAR_BEAR_DEATH, + ENTITY_POLAR_BEAR_HURT, + ENTITY_POLAR_BEAR_STEP, + ENTITY_POLAR_BEAR_WARNING, + ENTITY_PUFFER_FISH_AMBIENT, + ENTITY_PUFFER_FISH_BLOW_OUT, + ENTITY_PUFFER_FISH_BLOW_UP, + ENTITY_PUFFER_FISH_DEATH, + ENTITY_PUFFER_FISH_FLOP, + ENTITY_PUFFER_FISH_HURT, + ENTITY_PUFFER_FISH_STING, + ENTITY_RABBIT_AMBIENT, + ENTITY_RABBIT_ATTACK, + ENTITY_RABBIT_DEATH, + ENTITY_RABBIT_HURT, + ENTITY_RABBIT_JUMP, + ENTITY_RAVAGER_AMBIENT, + ENTITY_RAVAGER_ATTACK, + ENTITY_RAVAGER_CELEBRATE, + ENTITY_RAVAGER_DEATH, + ENTITY_RAVAGER_HURT, + ENTITY_RAVAGER_ROAR, + ENTITY_RAVAGER_STEP, + ENTITY_RAVAGER_STUNNED, + ENTITY_SALMON_AMBIENT, + ENTITY_SALMON_DEATH, + ENTITY_SALMON_FLOP, + ENTITY_SALMON_HURT("ENTITY_SALMON_FLOP"), + ENTITY_SHEEP_AMBIENT("SHEEP_IDLE"), + ENTITY_SHEEP_DEATH, + ENTITY_SHEEP_HURT, + ENTITY_SHEEP_SHEAR("SHEEP_SHEAR"), + ENTITY_SHEEP_STEP("SHEEP_WALK"), + ENTITY_SHULKER_AMBIENT, + ENTITY_SHULKER_BULLET_HIT, + ENTITY_SHULKER_BULLET_HURT, + ENTITY_SHULKER_CLOSE, + ENTITY_SHULKER_DEATH, + ENTITY_SHULKER_HURT, + ENTITY_SHULKER_HURT_CLOSED, + ENTITY_SHULKER_OPEN, + ENTITY_SHULKER_SHOOT, + ENTITY_SHULKER_TELEPORT, + ENTITY_SILVERFISH_AMBIENT("SILVERFISH_IDLE"), + ENTITY_SILVERFISH_DEATH("SILVERFISH_KILL"), + ENTITY_SILVERFISH_HURT("SILVERFISH_HIT"), + ENTITY_SILVERFISH_STEP("SILVERFISH_WALK"), + ENTITY_SKELETON_AMBIENT("SKELETON_IDLE"), + ENTITY_SKELETON_DEATH("SKELETON_DEATH"), + ENTITY_SKELETON_HORSE_AMBIENT("HORSE_SKELETON_IDLE"), + ENTITY_SKELETON_HORSE_AMBIENT_WATER, + ENTITY_SKELETON_HORSE_DEATH("HORSE_SKELETON_DEATH"), + ENTITY_SKELETON_HORSE_GALLOP_WATER, + ENTITY_SKELETON_HORSE_HURT("HORSE_SKELETON_HIT"), + ENTITY_SKELETON_HORSE_JUMP_WATER, + ENTITY_SKELETON_HORSE_STEP_WATER, + ENTITY_SKELETON_HORSE_SWIM, + ENTITY_SKELETON_HURT("SKELETON_HURT"), + ENTITY_SKELETON_SHOOT, + ENTITY_SKELETON_STEP("SKELETON_WALK"), + ENTITY_SLIME_ATTACK("SLIME_ATTACK"), + ENTITY_SLIME_DEATH, + ENTITY_SLIME_DEATH_SMALL, + ENTITY_SLIME_HURT, + ENTITY_SLIME_HURT_SMALL("ENTITY_SMALL_SLIME_HURT"), + ENTITY_SLIME_JUMP("SLIME_WALK"), + ENTITY_SLIME_JUMP_SMALL("SLIME_WALK2", "ENTITY_SMALL_SLIME_SQUISH"), + ENTITY_SLIME_SQUISH("SLIME_WALK2"), + ENTITY_SLIME_SQUISH_SMALL("ENTITY_SMALL_SLIME_SQUISH"), + ENTITY_SNOWBALL_THROW, + ENTITY_SNOW_GOLEM_AMBIENT("ENTITY_SNOWMAN_AMBIENT"), + ENTITY_SNOW_GOLEM_DEATH("ENTITY_SNOWMAN_DEATH"), + ENTITY_SNOW_GOLEM_HURT("ENTITY_SNOWMAN_HURT"), + ENTITY_SNOW_GOLEM_SHEAR, + ENTITY_SNOW_GOLEM_SHOOT("ENTITY_SNOWMAN_SHOOT"), + ENTITY_SPIDER_AMBIENT("SPIDER_IDLE"), + ENTITY_SPIDER_DEATH("SPIDER_DEATH"), + ENTITY_SPIDER_HURT, + ENTITY_SPIDER_STEP("SPIDER_WALK"), + ENTITY_SPLASH_POTION_BREAK, + ENTITY_SPLASH_POTION_THROW, + ENTITY_SQUID_AMBIENT, + ENTITY_SQUID_DEATH, + ENTITY_SQUID_HURT, + ENTITY_SQUID_SQUIRT, + ENTITY_STRAY_AMBIENT, + ENTITY_STRAY_DEATH, + ENTITY_STRAY_HURT, + ENTITY_STRAY_STEP, + ENTITY_STRIDER_AMBIENT, + ENTITY_STRIDER_DEATH, + ENTITY_STRIDER_EAT, + ENTITY_STRIDER_HAPPY, + ENTITY_STRIDER_HURT, + ENTITY_STRIDER_RETREAT, + ENTITY_STRIDER_SADDLE, + ENTITY_STRIDER_STEP, + ENTITY_STRIDER_STEP_LAVA, + ENTITY_TNT_PRIMED("FUSE"), + ENTITY_TROPICAL_FISH_AMBIENT, + ENTITY_TROPICAL_FISH_DEATH, + ENTITY_TROPICAL_FISH_FLOP("ENTITY_TROPICAL_FISH_DEATH"), + ENTITY_TROPICAL_FISH_HURT, + ENTITY_TURTLE_AMBIENT_LAND, + ENTITY_TURTLE_DEATH, + ENTITY_TURTLE_DEATH_BABY, + ENTITY_TURTLE_EGG_BREAK, + ENTITY_TURTLE_EGG_CRACK, + ENTITY_TURTLE_EGG_HATCH, + ENTITY_TURTLE_HURT, + ENTITY_TURTLE_HURT_BABY, + ENTITY_TURTLE_LAY_EGG, + ENTITY_TURTLE_SHAMBLE, + ENTITY_TURTLE_SHAMBLE_BABY, + ENTITY_TURTLE_SWIM, + ENTITY_VEX_AMBIENT, + ENTITY_VEX_CHARGE, + ENTITY_VEX_DEATH, + ENTITY_VEX_HURT, + ENTITY_VILLAGER_AMBIENT("VILLAGER_IDLE"), + ENTITY_VILLAGER_CELEBRATE, + ENTITY_VILLAGER_DEATH("VILLAGER_DEATH"), + ENTITY_VILLAGER_HURT("VILLAGER_HIT"), + ENTITY_VILLAGER_NO("VILLAGER_NO"), + ENTITY_VILLAGER_TRADE("VILLAGER_HAGGLE", "ENTITY_VILLAGER_TRADING"), + ENTITY_VILLAGER_WORK_ARMORER, + ENTITY_VILLAGER_WORK_BUTCHER, + ENTITY_VILLAGER_WORK_CARTOGRAPHER, + ENTITY_VILLAGER_WORK_CLERIC, + ENTITY_VILLAGER_WORK_FARMER, + ENTITY_VILLAGER_WORK_FISHERMAN, + ENTITY_VILLAGER_WORK_FLETCHER, + ENTITY_VILLAGER_WORK_LEATHERWORKER, + ENTITY_VILLAGER_WORK_LIBRARIAN, + ENTITY_VILLAGER_WORK_MASON, + ENTITY_VILLAGER_WORK_SHEPHERD, + ENTITY_VILLAGER_WORK_TOOLSMITH, + ENTITY_VILLAGER_WORK_WEAPONSMITH, + ENTITY_VILLAGER_YES("VILLAGER_YES"), + ENTITY_VINDICATOR_AMBIENT("ENTITY_VINDICATION_ILLAGER_AMBIENT"), + ENTITY_VINDICATOR_CELEBRATE, + ENTITY_VINDICATOR_DEATH("ENTITY_VINDICATION_ILLAGER_DEATH"), + ENTITY_VINDICATOR_HURT("ENTITY_VINDICATION_ILLAGER_HURT"), + ENTITY_WANDERING_TRADER_AMBIENT, + ENTITY_WANDERING_TRADER_DEATH, + ENTITY_WANDERING_TRADER_DISAPPEARED, + ENTITY_WANDERING_TRADER_DRINK_MILK, + ENTITY_WANDERING_TRADER_DRINK_POTION, + ENTITY_WANDERING_TRADER_HURT, + ENTITY_WANDERING_TRADER_NO, + ENTITY_WANDERING_TRADER_REAPPEARED, + ENTITY_WANDERING_TRADER_TRADE, + ENTITY_WANDERING_TRADER_YES, + ENTITY_WITCH_AMBIENT, + ENTITY_WITCH_CELEBRATE, + ENTITY_WITCH_DEATH, + ENTITY_WITCH_DRINK, + ENTITY_WITCH_HURT, + ENTITY_WITCH_THROW, + ENTITY_WITHER_AMBIENT("WITHER_IDLE"), + ENTITY_WITHER_BREAK_BLOCK, + ENTITY_WITHER_DEATH("WITHER_DEATH"), + ENTITY_WITHER_HURT("WITHER_HURT"), + ENTITY_WITHER_SHOOT("WITHER_SHOOT"), + ENTITY_WITHER_SKELETON_AMBIENT, + ENTITY_WITHER_SKELETON_DEATH, + ENTITY_WITHER_SKELETON_HURT, + ENTITY_WITHER_SKELETON_STEP, + ENTITY_WITHER_SPAWN("WITHER_SPAWN"), + ENTITY_WOLF_AMBIENT("WOLF_BARK"), + ENTITY_WOLF_DEATH("WOLF_DEATH"), + ENTITY_WOLF_GROWL("WOLF_GROWL"), + ENTITY_WOLF_HOWL("WOLF_HOWL"), + ENTITY_WOLF_HURT("WOLF_HURT"), + ENTITY_WOLF_PANT("WOLF_PANT"), + ENTITY_WOLF_SHAKE("WOLF_SHAKE"), + ENTITY_WOLF_STEP("WOLF_WALK"), + ENTITY_WOLF_WHINE("WOLF_WHINE"), + ENTITY_ZOGLIN_AMBIENT, + ENTITY_ZOGLIN_ANGRY, + ENTITY_ZOGLIN_ATTACK, + ENTITY_ZOGLIN_DEATH, + ENTITY_ZOGLIN_HURT, + ENTITY_ZOGLIN_STEP, + ENTITY_ZOMBIE_AMBIENT("ZOMBIE_IDLE"), + ENTITY_ZOMBIE_ATTACK_IRON_DOOR("ZOMBIE_METAL"), + ENTITY_ZOMBIE_ATTACK_WOODEN_DOOR("ZOMBIE_WOOD", "ENTITY_ZOMBIE_ATTACK_DOOR_WOOD"), + ENTITY_ZOMBIE_BREAK_WOODEN_DOOR("ZOMBIE_WOODBREAK", "ENTITY_ZOMBIE_BREAK_DOOR_WOOD"), + ENTITY_ZOMBIE_CONVERTED_TO_DROWNED, + ENTITY_ZOMBIE_DEATH("ZOMBIE_DEATH"), + ENTITY_ZOMBIE_DESTROY_EGG, + ENTITY_ZOMBIE_HORSE_AMBIENT("HORSE_ZOMBIE_IDLE"), + ENTITY_ZOMBIE_HORSE_DEATH("HORSE_ZOMBIE_DEATH"), + ENTITY_ZOMBIE_HORSE_HURT("HORSE_ZOMBIE_HIT"), + ENTITY_ZOMBIE_HURT("ZOMBIE_HURT"), + ENTITY_ZOMBIE_INFECT("ZOMBIE_INFECT"), + ENTITY_ZOMBIE_STEP("ZOMBIE_WALK"), + ENTITY_ZOMBIE_VILLAGER_AMBIENT, + ENTITY_ZOMBIE_VILLAGER_CONVERTED("ZOMBIE_UNFECT"), + + ENTITY_ZOMBIE_VILLAGER_CURE("ZOMBIE_REMEDY"), + ENTITY_ZOMBIE_VILLAGER_DEATH, + ENTITY_ZOMBIE_VILLAGER_HURT, + ENTITY_ZOMBIE_VILLAGER_STEP, + ENTITY_ZOMBIFIED_PIGLIN_AMBIENT("ZOMBE_PIG_IDLE", "ENTITY_ZOMBIE_PIG_AMBIENT", "ENTITY_ZOMBIE_PIGMAN_AMBIENT"), + ENTITY_ZOMBIFIED_PIGLIN_ANGRY("ZOMBIE_PIG_ANGRY", "ENTITY_ZOMBIE_PIG_ANGRY", "ENTITY_ZOMBIE_PIGMAN_ANGRY"), + ENTITY_ZOMBIFIED_PIGLIN_DEATH("ZOMBIE_PIG_DEATH", "ENTITY_ZOMBIE_PIG_DEATH", "ENTITY_ZOMBIE_PIGMAN_DEATH"), + ENTITY_ZOMBIFIED_PIGLIN_HURT("ZOMBIE_PIG_HURT", "ENTITY_ZOMBIE_PIG_HURT", "ENTITY_ZOMBIE_PIGMAN_HURT"), + EVENT_RAID_HORN, + ITEM_ARMOR_EQUIP_CHAIN, + ITEM_ARMOR_EQUIP_DIAMOND, + ITEM_ARMOR_EQUIP_ELYTRA, + ITEM_ARMOR_EQUIP_GENERIC, + ITEM_ARMOR_EQUIP_GOLD, + ITEM_ARMOR_EQUIP_IRON, + ITEM_ARMOR_EQUIP_LEATHER, + ITEM_ARMOR_EQUIP_NETHERITE, + ITEM_ARMOR_EQUIP_TURTLE, + ITEM_AXE_STRIP, + ITEM_BOOK_PAGE_TURN, + ITEM_BOOK_PUT, + ITEM_BOTTLE_EMPTY, + ITEM_BOTTLE_FILL, + ITEM_BOTTLE_FILL_DRAGONBREATH, + ITEM_BUCKET_EMPTY, + ITEM_BUCKET_EMPTY_FISH, + ITEM_BUCKET_EMPTY_LAVA, + ITEM_BUCKET_FILL, + ITEM_BUCKET_FILL_FISH, + ITEM_BUCKET_FILL_LAVA, + ITEM_CHORUS_FRUIT_TELEPORT, + ITEM_CROP_PLANT, + ITEM_CROSSBOW_HIT, + ITEM_CROSSBOW_LOADING_END, + ITEM_CROSSBOW_LOADING_MIDDLE, + ITEM_CROSSBOW_LOADING_START, + ITEM_CROSSBOW_QUICK_CHARGE_1, + ITEM_CROSSBOW_QUICK_CHARGE_2, + ITEM_CROSSBOW_QUICK_CHARGE_3, + ITEM_CROSSBOW_SHOOT, + ITEM_ELYTRA_FLYING, + ITEM_FIRECHARGE_USE, + ITEM_FLINTANDSTEEL_USE("FIRE_IGNITE"), + ITEM_HOE_TILL, + ITEM_HONEY_BOTTLE_DRINK, + ITEM_LODESTONE_COMPASS_LOCK, + ITEM_NETHER_WART_PLANT, + ITEM_SHIELD_BLOCK, + ITEM_SHIELD_BREAK, + ITEM_SHOVEL_FLATTEN, + ITEM_SWEET_BERRIES_PICK_FROM_BUSH, + ITEM_TOTEM_USE, + ITEM_TRIDENT_HIT, + ITEM_TRIDENT_HIT_GROUND, + ITEM_TRIDENT_RETURN, + ITEM_TRIDENT_RIPTIDE_1, + ITEM_TRIDENT_RIPTIDE_2("ITEM_TRIDENT_RIPTIDE_1"), + ITEM_TRIDENT_RIPTIDE_3("ITEM_TRIDENT_RIPTIDE_1"), + ITEM_TRIDENT_THROW, + ITEM_TRIDENT_THUNDER, + MUSIC_CREATIVE, + MUSIC_CREDITS, + MUSIC_DISC_11("RECORD_11"), + MUSIC_DISC_13("RECORD_13"), + MUSIC_DISC_BLOCKS("RECORD_BLOCKS"), + MUSIC_DISC_CAT("RECORD_CAT"), + MUSIC_DISC_CHIRP("RECORD_CHIRP"), + MUSIC_DISC_FAR("RECORD_FAR"), + MUSIC_DISC_MALL("RECORD_MALL"), + MUSIC_DISC_MELLOHI("RECORD_MELLOHI"), + MUSIC_DISC_PIGSTEP, + MUSIC_DISC_STAL("RECORD_STAL"), + MUSIC_DISC_STRAD("RECORD_STRAD"), + MUSIC_DISC_WAIT("RECORD_WAIT"), + MUSIC_DISC_WARD("RECORD_WARD"), + MUSIC_DRAGON, + MUSIC_END, + MUSIC_GAME, + MUSIC_MENU, + MUSIC_NETHER_BASALT_DELTAS("MUSIC_NETHER"), + MUSIC_NETHER_CRIMSON_FOREST, + MUSIC_NETHER_NETHER_WASTES, + MUSIC_NETHER_SOUL_SAND_VALLEY, + MUSIC_NETHER_WARPED_FOREST, + MUSIC_UNDER_WATER, + PARTICLE_SOUL_ESCAPE, + UI_BUTTON_CLICK("CLICK"), + UI_CARTOGRAPHY_TABLE_TAKE_RESULT, + UI_LOOM_SELECT_PATTERN, + UI_LOOM_TAKE_RESULT, + UI_STONECUTTER_SELECT_RECIPE, + UI_STONECUTTER_TAKE_RESULT, + UI_TOAST_CHALLENGE_COMPLETE, + UI_TOAST_IN, + UI_TOAST_OUT, + WEATHER_RAIN("AMBIENCE_RAIN"), + WEATHER_RAIN_ABOVE; + + + /** + * Cached list of {@link XSound#values()} to avoid allocating memory for + * calling the method every time. + * + * @since 2.0.0 + */ + public static final XSound[] VALUES = values(); + + + private final Sound sound; + + XSound( String... legacies) { + Sound bukkitSound = Data.BUKKIT_NAMES.get(this.name()); + if (bukkitSound == null) { + for (String legacy : legacies) { + bukkitSound = Data.BUKKIT_NAMES.get(legacy); + if (bukkitSound != null) break; + } + } + this.sound = bukkitSound; + + Data.NAMES.put(this.name(), this); + for (String legacy : legacies) { + Data.NAMES.putIfAbsent(legacy, this); + } + } + + /** + * Attempts to build the string like an enum name.
+ * Removes all the spaces, numbers and extra non-English characters. Also removes some config/in-game based strings. + * While this method is hard to maintain, it's extremely efficient. It's approximately more than x5 times faster than + * the normal RegEx + String Methods approach for both formatted and unformatted material names. + * + * @param name the sound name to format. + * @return an enum name. + * @since 1.0.0 + */ + + private static String format( String name) { + int len = name.length(); + char[] chs = new char[len]; + int count = 0; + boolean appendUnderline = false; + + for (int i = 0; i < len; i++) { + char ch = name.charAt(i); + + if (!appendUnderline && count != 0 && (ch == '-' || ch == ' ' || ch == '_') && chs[count] != '_') appendUnderline = true; + else { + boolean number = false; + // A few sounds have numbers in them. + if ((ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') || (number = (ch >= '0' && ch <= '9'))) { + if (appendUnderline) { + chs[count++] = '_'; + appendUnderline = false; + } + + if (number) chs[count++] = ch; + else chs[count++] = (char) (ch & 0x5f); + } + } + } + + return new String(chs, 0, count); + } + + /** + * Parses the XSound with the given name. + * + * @param sound the name of the sound. + * @return a matched XSound. + * @since 1.0.0 + */ + + public static Optional matchXSound( String sound) { + Validate.notEmpty(sound, "Cannot match XSound of a null or empty sound name"); + return Optional.ofNullable(Data.NAMES.get(format(sound))); + } + + /** + * Parses the XSound with the given bukkit sound. + * + * @param sound the Bukkit sound. + * @return a matched sound. + * @throws IllegalArgumentException may be thrown as an unexpected exception. + * @since 2.0.0 + */ + + public static XSound matchXSound( Sound sound) { + Objects.requireNonNull(sound, "Cannot match XSound of a null sound"); + return Objects.requireNonNull(Data.NAMES.get(sound.name()), () -> "Unsupported sound: " + sound.name()); + } + + /** + * @param player the player to play the sound to. + * @param sound the sound to play to the player. + * @see #play(Location, String) + * @since 1.0.0 + */ + + public static CompletableFuture play( Player player, String sound) { + Objects.requireNonNull(player, "Cannot play sound to null player"); + return parse(player, player.getLocation(), sound, true); + } + + /** + * @see #play(Location, String) + * @since 3.0.0 + */ + + public static CompletableFuture play( Location location, String sound) { + return parse(null, location, sound, true); + } + + /** + * Just an extra feature that loads sounds from strings. + * Useful for getting sounds from config files. + * Sounds are thread safe. + *

+ * It's strongly recommended to use this method while using it inside a loop. + * This can help to avoid parsing the sound properties multiple times. + * A simple usage of using it in a loop is: + *

+     *     Record record = XSound.parse(player, location, sound, false).join();
+     *     // Loop:
+     *     if (record != null) record.play();
+     * 
+ *

+ * This will also ignore {@code none} and {@code null} strings. + *

+ * Format: [LOC:]Sound, [Volume], [Pitch]
+ * Where {@code LOC:} will play the sound at the location if a player is specified. + * A sound played at a location will be heard by everyone around. + * Comma separators are optional. + *

+ * Examples: + *

+ *

+     *     LOC:ENTITY_PLAYER_BURP, 2.5f, 0.5
+     *     ENTITY_PLAYER_BURP, 0.5, 1f
+     *     BURP 0.5f 1
+     *     MUSIC_END, 10f
+     *     none
+     *     null
+     * 
+ *

+ * + * @param player the only player to play the sound to if requested to do so. + * @param location the location to play the sound to. + * @param sound the string of the sound with volume and pitch (if needed). + * @param play if the sound should be played right away. + * @since 3.0.0 + */ + + public static CompletableFuture parse( Player player, Location location, String sound, boolean play) { + Objects.requireNonNull(location, "Cannot play sound to null location"); + if (Strings.isNullOrEmpty(sound) || sound.equalsIgnoreCase("none")) return null; + + return CompletableFuture.supplyAsync(() -> { + String[] split = StringUtils.split(StringUtils.deleteWhitespace(sound), ','); + if (split.length == 0) split = StringUtils.split(sound, ' '); + + String name = split[0]; + boolean playAtLocation = player == null; + if (!playAtLocation && StringUtils.startsWithIgnoreCase(name, "loc:")) { + name = name.substring(4); + playAtLocation = true; + } + Optional typeOpt = matchXSound(name); + if (!typeOpt.isPresent()) return null; + Sound type = typeOpt.get().parseSound(); + if (type == null) return null; + + float volume = 1.0f; + float pitch = 1.0f; + + try { + if (split.length > 1) { + volume = Float.parseFloat(split[1]); + if (split.length > 2) pitch = Float.parseFloat(split[2]); + } + } catch (NumberFormatException ignored) { + } + + Record record = new Record(type, player, location, volume, pitch, playAtLocation); + if (play) record.play(); + return record; + }).exceptionally((ex) -> { + System.err.println("Could not play sound for string: " + sound); + ex.printStackTrace(); + return null; + }); + } + + /** + * Stops all the playing musics (not all the sounds) + *

+ * Note that this method will only work for the sound + * that are sent from {@link Player#playSound} and + * the sounds played from the client will not be + * affected by this. + * + * @param player the player to stop all the sounds from. + * @return the async task handling the operation. + * @see #stopSound(Player) + * @since 2.0.0 + */ + + public static CompletableFuture stopMusic( Player player) { + Objects.requireNonNull(player, "Cannot stop playing musics from null player"); + + return CompletableFuture.runAsync(() -> { + // We don't need to cache because it's rarely used. + XSound[] musics = {MUSIC_CREATIVE, MUSIC_CREDITS, + MUSIC_DISC_11, MUSIC_DISC_13, MUSIC_DISC_BLOCKS, MUSIC_DISC_CAT, MUSIC_DISC_CHIRP, + MUSIC_DISC_FAR, MUSIC_DISC_MALL, MUSIC_DISC_MELLOHI, MUSIC_DISC_STAL, + MUSIC_DISC_STRAD, MUSIC_DISC_WAIT, MUSIC_DISC_WARD, + MUSIC_DRAGON, MUSIC_END, MUSIC_GAME, MUSIC_MENU, MUSIC_NETHER_BASALT_DELTAS, MUSIC_UNDER_WATER, + MUSIC_NETHER_CRIMSON_FOREST, MUSIC_NETHER_WARPED_FOREST}; + + for (XSound music : musics) { + Sound sound = music.parseSound(); + if (sound != null) player.playSound(player.getLocation(), sound, 0F, 1F); + } + }); + } + + /** + * Plays an instrument's notes in an ascending form. + * This method is not really relevant to this utility class, but a nice feature. + * + * @param plugin the plugin handling schedulers. + * @param player the player to play the note from. + * @param playTo the entity to play the note to. + * @param instrument the instrument. + * @param ascendLevel the ascend level of notes. Can only be positive and not higher than 7 + * @param delay the delay between each play. + * @return the async task handling the operation. + * @since 2.0.0 + */ + + public static BukkitTask playAscendingNote( JavaPlugin plugin, Player player, Entity playTo, Instrument instrument, + int ascendLevel, int delay) { + Objects.requireNonNull(player, "Cannot play note from null player"); + Objects.requireNonNull(playTo, "Cannot play note to null entity"); + + Validate.isTrue(ascendLevel > 0, "Note ascend level cannot be lower than 1"); + Validate.isTrue(ascendLevel <= 7, "Note ascend level cannot be greater than 7"); + Validate.isTrue(delay > 0, "Delay ticks must be at least 1"); + + return new BukkitRunnable() { + int repeating = ascendLevel; + + @Override + public void run() { + player.playNote(playTo.getLocation(), instrument, Note.natural(1, Note.Tone.values()[ascendLevel - repeating])); + if (repeating-- == 0) cancel(); + } + }.runTaskTimerAsynchronously(plugin, 0, delay); + } + + /** + * In most cases your should be using {@link #name()} instead. + * + * @return a friendly readable string name. + */ + @Override + public String toString() { + return WordUtils.capitalize(this.name().replace('_', ' ').toLowerCase(Locale.ENGLISH)); + } + + /** + * Parses the XSound as a {@link Sound} based on the server version. + * + * @return the vanilla sound. + * @since 1.0.0 + */ + + public Sound parseSound() { + return this.sound; + } + + /** + * Checks if this sound is supported in the current Minecraft version. + *

+ * An invocation of this method yields exactly the same result as the expression: + *

+ *

+ * {@link #parseSound()} != null + *
+ * + * @return true if the current version has this sound, otherwise false. + * @since 1.0.0 + */ + public boolean isSupported() { + return this.parseSound() != null; + } + + /** + * Plays a sound repeatedly with the given delay at a moving target's location. + * + * @param plugin the plugin handling schedulers. (You can replace this with a static instance) + * @param entity the entity to play the sound to. We exactly need an entity to keep the track of location changes. + * @param volume the volume of the sound. + * @param pitch the pitch of the sound. + * @param repeat the amount of times to repeat playing. + * @param delay the delay between each repeat. + * @return the async task handling this operation. + * @see #play(Location, float, float) + * @since 2.0.0 + */ + + public BukkitTask playRepeatedly( JavaPlugin plugin, Entity entity, float volume, float pitch, int repeat, int delay) { + Objects.requireNonNull(plugin, "Cannot play repeating sound from null plugin"); + Objects.requireNonNull(entity, "Cannot play repeating sound at null location"); + + Validate.isTrue(repeat > 0, "Cannot repeat playing sound " + repeat + " times"); + Validate.isTrue(delay > 0, "Delay ticks must be at least 1"); + + return new BukkitRunnable() { + int repeating = repeat; + + @Override + public void run() { + play(entity.getLocation(), volume, pitch); + if (repeating-- == 0) cancel(); + } + }.runTaskTimer(plugin, 0, delay); + } + + /** + * Stops playing the specified sound from the player. + * + * @param player the player to stop playing the sound to. + * @see #stopMusic(Player) + * @since 2.0.0 + */ + public void stopSound( Player player) { + Objects.requireNonNull(player, "Cannot stop playing sound from null player"); + + Sound sound = this.parseSound(); + if (sound != null) player.playSound(player.getLocation(), sound, 0F, 1F); + } + + /** + * Plays a normal sound to an entity. + * + * @param entity the entity to play the sound to. + * @since 1.0.0 + */ + public void play( Entity entity) { + play(entity, 1.0f, 1.0f); + } + + /** + * Plays a sound to an entity with the given volume and pitch. + * + * @param entity the entity to play the sound to. + * @param volume the volume of the sound, 1 is normal. + * @param pitch the pitch of the sound, 0 is normal. + * @since 1.0.0 + */ + public void play( Entity entity, float volume, float pitch) { + Objects.requireNonNull(entity, "Cannot play sound to a null entity"); + if (entity instanceof Player) { + Sound sound = this.parseSound(); + if (sound != null) ((Player) entity).playSound(entity.getLocation(), sound, volume, pitch); + } else { + play(entity.getLocation(), volume, pitch); + } + } + + /** + * Plays a normal sound in a location. + * + * @param location the location to play the sound in. + * @since 2.0.0 + */ + public void play( Location location) { + play(location, 1.0f, 1.0f); + } + + /** + * Plays a sound in a location with the given volume and pitch. + * + * @param location the location to play this sound. + * @param volume the volume of the sound, 1 is normal. + * @param pitch the pitch of the sound, 0 is normal. + * @since 2.0.0 + */ + public void play( Location location, float volume, float pitch) { + Objects.requireNonNull(location, "Cannot play sound to null location"); + Sound sound = this.parseSound(); + if (sound != null) location.getWorld().playSound(location, sound, volume, pitch); + } + + /** + * Used for datas that need to be accessed during enum initilization. + * + * @since 5.0.0 + */ + private static final class Data { + /** + * Just for enum initialization. + * + * @since 5.0.0 + */ + private static final WeakHashMap BUKKIT_NAMES = new WeakHashMap<>(); + /** + * We don't want to use {@link Enums#getIfPresent(Class, String)} to avoid a few checks. + * + * @since 3.1.0 + */ + private static final Map NAMES = new HashMap<>(); + + static { + for (Sound sound : Sound.values()) BUKKIT_NAMES.put(sound.name(), sound); + } + } + + /** + * A class to help caching sound properties parsed from config. + * + * @since 3.0.0 + */ + public static class Record { + public final Sound sound; + public final Player player; + public final Location location; + public final float volume; + public final float pitch; + public final boolean playAtLocation; + + public Record( Sound sound, Player player, Location location, float volume, float pitch, boolean playAtLocation) { + this.sound = sound; + this.player = player; + this.location = location; + this.volume = volume; + this.pitch = pitch; + this.playAtLocation = playAtLocation; + } + + /** + * Plays the sound with the given options and updating the players location. + * + * @since 3.0.0 + */ + public void play() { + play(player == null ? location : player.getLocation()); + } + + /** + * Plays the sound with the updated location. + * + * @param updatedLocation the upated location. + * @since 3.0.0 + */ + public void play( Location updatedLocation) { + if (playAtLocation) location.getWorld().playSound(updatedLocation, sound, volume, pitch); + else if (player.isOnline()) player.playSound(updatedLocation, sound, volume, pitch); + } + } +} diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml new file mode 100644 index 0000000..407968b --- /dev/null +++ b/src/main/resources/config.yml @@ -0,0 +1,65 @@ +prefix: '&7[&a&lFuture&2&lHolograms&7] &8↣ &r' + +messages: + onlyPlayers: + - '{center}&8&m &c&l¡ !&8&m ' + - '{center}&cThis command is only for players!' + - '{center}&8&m ' + error: + - '{center}&8&m &c&l¡ !&8&m ' + - '{center}&cAn error occured while executing the command.' + - '{center}&cCheck the console for log.' + - '{center}&8&m ' + commandNoExists: '{prefix}&cThat command doesn''t exist!' + noPermission: + - '{center}&8&m &c&l¡ !&8&m ' + - '{center}&cYou don''t have permissions to do this!' + - '{center}&8&m ' + commands: + help: + - '{center}&e&m ' + - '' + - '{center}&a&lFuture&2&lHolograms &7- &aHelp page' + - '{center}&e<> &8= &7Optional&8, &c[] &8= &7Required' + - '' + - '{cmd}' + - '' + - '{center}&e&m ' + create: + help: '{center}&7- /&2%alias% &ecreate [name] &8- &aCreate a new hologram.' + success: '{prefix}&aHologram created sucessfully!' + alreadyExist: + - '{center}&8&m &c&l¡ !&8&m ' + - '{center}&cThat hologram already exist!' + - '{center}&8&m ' + remove: + help: '{center}&7- /&2%alias% &edelete [name] &8- &aRemove and delete an hologram.' + success: '{prefix}&cHologram removed!' + notExist: '{prefix}&cThat hologram doesn''t exist!' + setlocation: + help: '{center}&7- /&2%alias% &esetlocation [name] &8- &aSet the location of hologram.' + success: '{prefix}&aYou''ve been set the new location for that hologram!' + notExist: '{prefix}&cThat hologram doesn''t exist!' + setexactlylocation: + help: '{center}&7- /&2%alias% &esetexactlylocation [name] &8- &aSet the exactly location of hologram.' + success: '{prefix}&aYou''ve been set the new location for that hologram!' + notExist: '{prefix}&cThat hologram doesn''t exist!' + list: + help: '{center}&7- /&2%alias% &elist &8- &aGet a list of all holograms.' + hologramFormat: '&7- &b%name% &8/ &c%location%' + noLocation: '&cNo Location.' + format: + - '{center}&e&m ' + - '' + - '{center}&a&lFuture&2&lHolograms &7- &aHolograms List' + - '' + - '{list}' + - '' + - '{center}&e&m ' + reload: + help: '{center}&7- /&2%alias% &ereload &8- &aReload all or specific hologram.' + success: '{prefix}&aAll holograms have been reloaded!' + config: '{prefix}&aConfiguration reloaded!' + success2: '{prefix}&aHologram reloaded!' + notExist: '{prefix}&cThat hologram doesn''t exist!' + noHolograms: '{prefix}&cThere is any hologram configurated to reload!' diff --git a/src/main/resources/holograms.yml b/src/main/resources/holograms.yml new file mode 100644 index 0000000..19ba2b8 --- /dev/null +++ b/src/main/resources/holograms.yml @@ -0,0 +1,26 @@ +hologram1: + cooldown: 20 + location: null + default: var1 + refresh: true + refreshRate: 20 + var1: + next: var2 + lines: + - '&cHologram #1 &7(&e&lExample&7)' + - '' + - '&7- &a%player_name%' + - '' + - '&b&lVar1 &f&lVar2' + actions: + - '[sound]UI_BUTTON_CLICK,10.0,1.0' + var2: + next: var1 + lines: + - '&cHologram #2 &7(&e&lExample&7)' + - '' + - '&7- &c%player_displayname%' + - '' + - '&f&lVar1 &b&lVar2' + actions: + - '[sound]UI_BUTTON_CLICK,10.0,1.0' diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml new file mode 100644 index 0000000..63b4204 --- /dev/null +++ b/src/main/resources/plugin.yml @@ -0,0 +1,13 @@ +name: FutureHolograms +version: ${project.version} +main: me.TheJokerDev.futureholograms.Main +api-version: 1.16 +softdepend: [ PlaceholderAPI, HolographicDisplays ] +authors: [ TheJokerDev ] +description: Create custom holograms with uniques options. +website: https://github.com/TheJokerDev + +commands: + futureholograms: + aliases: [fholo, fholograms, futureholo] + description: Main command for the plugin.