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..6a9a135 --- /dev/null +++ b/pom.xml @@ -0,0 +1,171 @@ + + + 4.0.0 + + dev.qv7_ + SnakeHub + 1.2.0-HOTFIX + jar + + SnakeHub + + + 1.8 + UTF-8 + + + + + + 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/ + + + dmulloy2-repo + https://repo.dmulloy2.net/repository/public/ + + + jitpack.io + https://jitpack.io/ + + + + placeholderapi + http://repo.extendedclip.com/content/repositories/placeholderapi/ + + + + viaversion-repo + https://repo.viaversion.com/ + + + sonatype + https://oss.sonatype.org/content/groups/public/ + + + + + + org.projectlombok + lombok + 1.18.22 + provided + + + org.spigotmc + spigot-api + 1.8.8-R0.1-SNAPSHOT + provided + + + com.viaversion + viaversion + 4.2.0-SNAPSHOT + provided + + + com.spigot + Spigot + LATEST + system + ${project.basedir}/depends/Spigot1.8.jar + + + net.hylist.spigot + Spigot + LATEST + system + ${project.basedir}/depends/spigot.jar + + + com.comphenix.protocol + ProtocolLib + 4.7.0 + + + dev.alex.net.utilities.command + Spigot-Utilities-Command + 1.0 + system + ${project.basedir}/depends/Spigot-Utilities-Command-1.0.jar + + + net.milkbowl.vault + Vault + 1.2.27 + system + ${project.basedir}/depends/Vault.jar + + + aqua + aqua + LATEST + system + ${project.basedir}/depends/DL-AquaCore_2.6.20-Cracked_2.jar + + + net.lunarclient + LunarClient + LATEST + system + ${project.basedir}/depends/LunarAPI.jar + + + placeholder + Placeholder + LATEST + system + ${project.basedir}/depends/PlaceholderAPI.jar + + + net.luckperms + api + 5.0 + provided + + + me.signatured.ezqueuespigot + EzqueueSpigot + 1.6.5 + system + ${project.basedir}/depends/EzQueueSpigot.jar + + + diff --git a/src/main/java/dev/aapy/SnakeHub.java b/src/main/java/dev/aapy/SnakeHub.java new file mode 100644 index 0000000..0a1b88e --- /dev/null +++ b/src/main/java/dev/aapy/SnakeHub.java @@ -0,0 +1,82 @@ +package dev.aapy; + +import dev.aapy.file.Config; +import dev.aapy.file.Message; +import dev.aapy.file.Scoreboard; +import dev.aapy.file.Tablist; +import dev.aapy.listeners.hotbar.PvPListener; +import dev.aapy.manager.Manager; +import dev.aapy.manager.managers.PermissionManager; +import dev.aapy.tablist.Tab; +import dev.aapy.tablist.provider.TablistProvider; +import dev.aapy.util.CC; +import lombok.Getter; +import org.bukkit.Bukkit; +import org.bukkit.World; +import org.bukkit.plugin.java.JavaPlugin; + +@Getter +public class SnakeHub extends JavaPlugin { + + private static SnakeHub plugin; + private PermissionManager permission; + private Manager manager; + private PvPListener pvpListener; + + @Override + public void onEnable() { + plugin = this; + + this.manager = new Manager(this); + this.manager.enable(); + CC.log("&cSnakeHub &f" + this.manager.getManagers().size() + " &amanagers have been registered"); + + CC.log("&f"); + this.permission = new PermissionManager(this); + this.permission.loadHook(); + + Bukkit.getMessenger().registerOutgoingPluginChannel(this, "BungeeCord"); + CC.log("&aBungeeCoord connecting!"); + + Message.getConfig().load(); + Scoreboard.getConfig().load(); + Tablist.getConfig().load(); + Config.getConfig().load(); + + CC.log("&7&m========================="); + CC.log(""); + CC.log("&cPlugin Name: &fSnakeHub"); + CC.log("&cVersion: &f1.2.0-HOTFIX"); + CC.log("&cAuthor: &fAapy#0001"); + CC.log(""); + CC.log("&7&m========================="); + + for (World world : Bukkit.getWorlds()) { + world.setGameRuleValue("doDaylightCycle", "false"); + world.setGameRuleValue("doMobSpawning", "false"); + world.setTime(6000L); + } + + if (Config.getConfig().getBoolean("BOOLEANS.TABLIST")) { + new Tab(this, new TablistProvider()); + } + + Message.getConfig().save(); + Scoreboard.getConfig().save(); + Tablist.getConfig().save(); + Config.getConfig().save(); + } + + @Override + public void onDisable() { + this.manager.disable(); + Message.getConfig().save(); + Scoreboard.getConfig().save(); + Tablist.getConfig().save(); + Config.getConfig().save(); + } + + public static SnakeHub getInst() { + return plugin; + } +} \ No newline at end of file diff --git a/src/main/java/dev/aapy/commands/plugin/HubCore.java b/src/main/java/dev/aapy/commands/plugin/HubCore.java new file mode 100644 index 0000000..5bfc9d1 --- /dev/null +++ b/src/main/java/dev/aapy/commands/plugin/HubCore.java @@ -0,0 +1,17 @@ +package dev.aapy.commands.plugin; + +import dev.alex.net.utilities.command.command.CommandExecutor; + +/** + * @author 7qv_ and Alexito2060 on 19/2/2022. + * @project SnakeHub + */ + +public class HubCore extends CommandExecutor { + + public HubCore() { + super("HubCore", "HubCore command"); + registerArgument(new HubInfo()); + registerArgument(new HubReload()); + } +} diff --git a/src/main/java/dev/aapy/commands/plugin/HubInfo.java b/src/main/java/dev/aapy/commands/plugin/HubInfo.java new file mode 100644 index 0000000..57796eb --- /dev/null +++ b/src/main/java/dev/aapy/commands/plugin/HubInfo.java @@ -0,0 +1,30 @@ +package dev.aapy.commands.plugin; + +import dev.alex.net.utilities.command.command.CommandArgument; +import dev.aapy.util.CC; +import org.bukkit.command.CommandSender; + +/** + * @author 7qv_ and Alexito2060 on 19/2/2022. + * @project SnakeHub + */ +public class HubInfo extends CommandArgument { + + public HubInfo() { super("info", "See SnakeHub information"); } + + @Override + public String getUsage(String s) { return getName(); } + + @Override + public boolean onCommand(CommandSender sender, String label, String[] args) { + sender.sendMessage(CC.translate("&7&m----------------------------")); + sender.sendMessage(""); + sender.sendMessage(CC.translate("&bSnakeHub &7- &7[&fHubCore&7]")); + sender.sendMessage(""); + sender.sendMessage(CC.translate("&7» &cVersion&7: &f1.0.3-RECODE")); + sender.sendMessage(CC.translate("&7» &cAuthor&7: &f7qv_")); + sender.sendMessage(""); + sender.sendMessage(CC.translate("&7&m----------------------------")); + return false; + } +} diff --git a/src/main/java/dev/aapy/commands/plugin/HubReload.java b/src/main/java/dev/aapy/commands/plugin/HubReload.java new file mode 100644 index 0000000..9007b27 --- /dev/null +++ b/src/main/java/dev/aapy/commands/plugin/HubReload.java @@ -0,0 +1,33 @@ +package dev.aapy.commands.plugin; + +import dev.alex.net.utilities.command.command.CommandArgument; +import dev.aapy.file.Config; +import dev.aapy.file.Message; +import dev.aapy.file.Scoreboard; +import dev.aapy.file.Tablist; +import dev.aapy.util.CC; +import org.bukkit.command.CommandSender; + +/** + * @author 7qv_ and Alexito2060 on 19/2/2022. + * @project SnakeHub + */ +public class HubReload extends CommandArgument { + + public HubReload() { super("reload", "Reload configs file", "hub.reload"); } + + @Override + public String getUsage(String s) { return getName(); } + + @Override + public boolean onCommand(CommandSender sender, String label, String[] args) { + Config.getConfig().reload(); + Message.getConfig().reload(); + Scoreboard.getConfig().reload(); + Tablist.getConfig().reload(); + + sender.sendMessage(CC.translate("&aAll files has been successfully reloaded.")); + + return true; + } +} diff --git a/src/main/java/dev/aapy/commands/social/Discord.java b/src/main/java/dev/aapy/commands/social/Discord.java new file mode 100644 index 0000000..ca1c054 --- /dev/null +++ b/src/main/java/dev/aapy/commands/social/Discord.java @@ -0,0 +1,28 @@ +package dev.aapy.commands.social; + +import dev.alex.net.utilities.command.command.CommandExecutor; +import dev.aapy.file.Config; +import dev.aapy.file.Message; +import dev.aapy.util.CC; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; + +/** + * @author 7qv_ and Alexito2060 on 19/2/2022. + * @project SnakeHub + */ +public class Discord extends CommandExecutor { + + public Discord() { + super("discord", "Discord command", "hubcore.discord.command", new String[]{"dc"}); + } + + @Override + public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + Message.getConfig().getStringList("SOCIAL.DISCORD").forEach((s) -> { + sender.sendMessage(CC.translate(s.replace("{discord}", Config.getConfig().getString("SOCIAL.DISCORD")))); + }); + return true; + } +} + diff --git a/src/main/java/dev/aapy/commands/social/Store.java b/src/main/java/dev/aapy/commands/social/Store.java new file mode 100644 index 0000000..d9df459 --- /dev/null +++ b/src/main/java/dev/aapy/commands/social/Store.java @@ -0,0 +1,27 @@ +package dev.aapy.commands.social; + +import dev.alex.net.utilities.command.command.CommandExecutor; +import dev.aapy.file.Config; +import dev.aapy.file.Message; +import dev.aapy.util.CC; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; + +/** + * @author 7qv_ and Alexito2060 on 19/2/2022. + * @project SnakeHub + */ +public class Store extends CommandExecutor { + + public Store() { + super("store", "Store Command", "hubcore.store.command"); + } + + @Override + public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + Message.getConfig().getStringList("SOCIAL.STORE").forEach((s) -> { + sender.sendMessage(CC.translate(s.replace("{store}", Config.getConfig().getString("SOCIAL.STORE")))); + }); + return true; + } +} diff --git a/src/main/java/dev/aapy/commands/social/TeamSpeak.java b/src/main/java/dev/aapy/commands/social/TeamSpeak.java new file mode 100644 index 0000000..ed8b69b --- /dev/null +++ b/src/main/java/dev/aapy/commands/social/TeamSpeak.java @@ -0,0 +1,27 @@ +package dev.aapy.commands.social; + +import dev.alex.net.utilities.command.command.CommandExecutor; +import dev.aapy.file.Config; +import dev.aapy.file.Message; +import dev.aapy.util.CC; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; + +/** + * @author 7qv_ and Alexito2060 on 19/2/2022. + * @project SnakeHub + */ +public class TeamSpeak extends CommandExecutor { + + public TeamSpeak() { + super("teamspeak", "TeamSpeak Command", "hubcore.teamspeak.command", new String[]{"ts"}); + } + + @Override + public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + Message.getConfig().getStringList("SOCIAL.TEAMSPEAK").forEach((s) -> { + sender.sendMessage(CC.translate(s.replace("{team-speak}", Config.getConfig().getString("SOCIAL.TEAMSPEAK")))); + }); + return true; + } +} diff --git a/src/main/java/dev/aapy/commands/social/Twitter.java b/src/main/java/dev/aapy/commands/social/Twitter.java new file mode 100644 index 0000000..f622de8 --- /dev/null +++ b/src/main/java/dev/aapy/commands/social/Twitter.java @@ -0,0 +1,27 @@ +package dev.aapy.commands.social; + +import dev.alex.net.utilities.command.command.CommandExecutor; +import dev.aapy.file.Config; +import dev.aapy.file.Message; +import dev.aapy.util.CC; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; + +/** + * @author 7qv_ and Alexito2060 on 19/2/2022. + * @project SnakeHub + */ +public class Twitter extends CommandExecutor { + + public Twitter() { + super("twitter", "Twitter Command", "hubcore.twitter.command"); + } + + @Override + public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + Message.getConfig().getStringList("SOCIAL.TWITTER").forEach((s) -> { + sender.sendMessage(CC.translate(s.replace("{twitter}", Config.getConfig().getString("SOCIAL.TWITTER")))); + }); + return true; + } +} diff --git a/src/main/java/dev/aapy/commands/social/WebSite.java b/src/main/java/dev/aapy/commands/social/WebSite.java new file mode 100644 index 0000000..7ff7567 --- /dev/null +++ b/src/main/java/dev/aapy/commands/social/WebSite.java @@ -0,0 +1,27 @@ +package dev.aapy.commands.social; + +import dev.alex.net.utilities.command.command.CommandExecutor; +import dev.aapy.file.Config; +import dev.aapy.file.Message; +import dev.aapy.util.CC; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; + +/** + * @author 7qv_ and Alexito2060 on 19/2/2022. + * @project SnakeHub + */ +public class WebSite extends CommandExecutor { + + public WebSite() { + super("website", "WebSite Command","hubcore.website.command"); + } + + @Override + public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + Message.getConfig().getStringList("SOCIAL.WEBSITE").forEach((s) -> { + sender.sendMessage(CC.translate(s.replace("{website}", Config.getConfig().getString("SOCIAL.WEBSITE")))); + }); + return true; + } +} diff --git a/src/main/java/dev/aapy/file/Config.java b/src/main/java/dev/aapy/file/Config.java new file mode 100644 index 0000000..b7a29b2 --- /dev/null +++ b/src/main/java/dev/aapy/file/Config.java @@ -0,0 +1,61 @@ +package dev.aapy.file; + +import dev.aapy.SnakeHub; +import org.bukkit.configuration.file.*; +import org.bukkit.plugin.*; + +import java.io.File; + +/** + * @author 7qv_ on 8/2/2022. + * @project SnakeHub + */ +public class Config extends YamlConfiguration +{ + private static Config config; + private Plugin plugin; + private File configFile; + + public static Config getConfig() { + if (Config.config == null) { + Config.config = new Config(); + } + return Config.config; + } + + private Plugin main() { + return (Plugin) SnakeHub.getInst(); + } + + public Config() { + this.plugin = this.main(); + this.configFile = new File(this.plugin.getDataFolder(), "config.yml"); + if (!this.configFile.exists()) { + this.plugin.saveResource("config.yml", false); + } + this.reload(); + } + + public void reload() { + try { + super.load(this.configFile); + } + catch (Exception e) { + e.printStackTrace(); + } + } + + public void load() { + try { + super.save(this.configFile); + } + catch (Exception e) { + e.printStackTrace(); + } + } + + public void save() { + this.load(); + this.reload(); + } +} diff --git a/src/main/java/dev/aapy/file/Message.java b/src/main/java/dev/aapy/file/Message.java new file mode 100644 index 0000000..bf12f94 --- /dev/null +++ b/src/main/java/dev/aapy/file/Message.java @@ -0,0 +1,60 @@ +package dev.aapy.file; +import dev.aapy.SnakeHub; +import org.bukkit.configuration.file.*; +import org.bukkit.plugin.*; + +import java.io.File; + +/** + * @author 7qv_ on 9/2/2022. + * @project SnakeHub + */ +public class Message extends YamlConfiguration +{ + private static Message config; + private Plugin plugin; + private File configFile; + + public static Message getConfig() { + if (Message.config == null) { + Message.config = new Message(); + } + return Message.config; + } + + private Plugin main() { + return (Plugin) SnakeHub.getInst(); + } + + public Message() { + this.plugin = this.main(); + this.configFile = new File(this.plugin.getDataFolder(), "lang.yml"); + if (!this.configFile.exists()) { + this.plugin.saveResource("lang.yml", false); + } + this.reload(); + } + + public void reload() { + try { + super.load(this.configFile); + } + catch (Exception e) { + e.printStackTrace(); + } + } + + public void load() { + try { + super.save(this.configFile); + } + catch (Exception e) { + e.printStackTrace(); + } + } + + public void save() { + this.load(); + this.reload(); + } +} diff --git a/src/main/java/dev/aapy/file/Scoreboard.java b/src/main/java/dev/aapy/file/Scoreboard.java new file mode 100644 index 0000000..1ea4c15 --- /dev/null +++ b/src/main/java/dev/aapy/file/Scoreboard.java @@ -0,0 +1,61 @@ +package dev.aapy.file; + +import dev.aapy.SnakeHub; +import org.bukkit.configuration.file.*; +import org.bukkit.plugin.*; + +import java.io.File; + +/** + * @author 7qv_ on 9/2/2022. + * @project SnakeHub + */ +public class Scoreboard extends YamlConfiguration +{ + private static Scoreboard config; + private Plugin plugin; + private File configFile; + + public static Scoreboard getConfig() { + if (Scoreboard.config == null) { + Scoreboard.config = new Scoreboard(); + } + return Scoreboard.config; + } + + private Plugin main() { + return (Plugin) SnakeHub.getInst(); + } + + public Scoreboard() { + this.plugin = this.main(); + this.configFile = new File(this.plugin.getDataFolder(), "scoreboard.yml"); + if (!this.configFile.exists()) { + this.plugin.saveResource("scoreboard.yml", false); + } + this.reload(); + } + + public void reload() { + try { + super.load(this.configFile); + } + catch (Exception e) { + e.printStackTrace(); + } + } + + public void load() { + try { + super.save(this.configFile); + } + catch (Exception e) { + e.printStackTrace(); + } + } + + public void save() { + this.load(); + this.reload(); + } +} diff --git a/src/main/java/dev/aapy/file/Tablist.java b/src/main/java/dev/aapy/file/Tablist.java new file mode 100644 index 0000000..5e4f146 --- /dev/null +++ b/src/main/java/dev/aapy/file/Tablist.java @@ -0,0 +1,62 @@ +package dev.aapy.file; + + +import dev.aapy.SnakeHub; +import org.bukkit.configuration.file.*; +import org.bukkit.plugin.*; + +import java.io.File; + +/** + * @author 7qv_ on 10/2/2022. + * @project SnakeHub + */ +public class Tablist extends YamlConfiguration +{ + private static Tablist config; + private Plugin plugin; + private File configFile; + + public static Tablist getConfig() { + if (Tablist.config == null) { + Tablist.config = new Tablist(); + } + return Tablist.config; + } + + private Plugin main() { + return (Plugin) SnakeHub.getInst(); + } + + public Tablist() { + this.plugin = this.main(); + this.configFile = new File(this.plugin.getDataFolder(), "tab.yml"); + if (!this.configFile.exists()) { + this.plugin.saveResource("tab.yml", false); + } + this.reload(); + } + + public void reload() { + try { + super.load(this.configFile); + } + catch (Exception e) { + e.printStackTrace(); + } + } + + public void load() { + try { + super.save(this.configFile); + } + catch (Exception e) { + e.printStackTrace(); + } + } + + public void save() { + this.load(); + this.reload(); + } +} diff --git a/src/main/java/dev/aapy/listeners/ChatFormatListener.java b/src/main/java/dev/aapy/listeners/ChatFormatListener.java new file mode 100644 index 0000000..48949b6 --- /dev/null +++ b/src/main/java/dev/aapy/listeners/ChatFormatListener.java @@ -0,0 +1,31 @@ +package dev.aapy.listeners; + +import dev.aapy.SnakeHub; +import dev.aapy.file.Config; +import dev.aapy.util.CC; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.AsyncPlayerChatEvent; + +/** + * @author 7qv_ on 11/2/2022. + * @project SnakeHub + */ +public class ChatFormatListener implements Listener { + + @EventHandler + public void onChatFormat(AsyncPlayerChatEvent event) { + Player p = event.getPlayer(); + + for (String chat : Config.getConfig().getStringList("CHAT-FORMAT")) { + + chat = chat.replace("{prefix}", SnakeHub.getInst().getPermission().getPermission().getPrefix(p)); + chat = chat.replace("{ign}", p.getName()); + + chat = chat.replace("{message}", event.getMessage()); + + event.setFormat(CC.translate(chat)); + } + } +} diff --git a/src/main/java/dev/aapy/listeners/DeveloperListener.java b/src/main/java/dev/aapy/listeners/DeveloperListener.java new file mode 100644 index 0000000..8ceb7ca --- /dev/null +++ b/src/main/java/dev/aapy/listeners/DeveloperListener.java @@ -0,0 +1,32 @@ +package dev.aapy.listeners; + +import dev.aapy.util.CC; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerJoinEvent; + +/** + * @author 7qv_ on 7/2/2022. + * @project SnakeHub + */ +public class DeveloperListener implements Listener { + + @EventHandler + public void onJoinDev(PlayerJoinEvent event) { + Player p = event.getPlayer(); + + if (p.getName().equals("7qv_")) { + p.sendMessage(CC.translate("&7&m----------------------------")); + p.sendMessage(""); + p.sendMessage(CC.translate("&cSnakeHub &7- &7[&fHubCore&7]")); + p.sendMessage(""); + p.sendMessage(CC.translate("&7» &cVersion&7: &f1.0.3-RECODE")); + p.sendMessage(CC.translate("&7» &cAuthor&7: &f7qv_")); + p.sendMessage(""); + p.sendMessage(CC.translate("&7&m----------------------------")); + } + + } + +} diff --git a/src/main/java/dev/aapy/listeners/JumpListener.java b/src/main/java/dev/aapy/listeners/JumpListener.java new file mode 100644 index 0000000..dd65e37 --- /dev/null +++ b/src/main/java/dev/aapy/listeners/JumpListener.java @@ -0,0 +1,73 @@ +package dev.aapy.listeners; + +import dev.aapy.SnakeHub; +import org.bukkit.*; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.EntityDamageEvent; +import org.bukkit.event.player.PlayerMoveEvent; +import org.bukkit.event.player.PlayerToggleFlightEvent; +import org.bukkit.plugin.Plugin; + +/** + * @author 7qv_ on 17/2/2022. + * @project SnakeHub + */ +public class JumpListener implements Listener { + + @EventHandler + public void onPlayerToggleFlight(final PlayerToggleFlightEvent event) { + final Player player = event.getPlayer(); + final Sound sound = Sound.ZOMBIE_INFECT; + if (player.getGameMode() == GameMode.CREATIVE) { + return; + } + event.setCancelled(true); + player.setAllowFlight(false); + player.setFlying(false); + player.setVelocity(player.getLocation().getDirection().multiply(1.5).setY(1)); + player.playSound(player.getLocation(), sound, 1.0f, 0.0f); + } + + @EventHandler + public void onPlayerMove(final PlayerMoveEvent event) { + final Player player = event.getPlayer(); + if (player.getGameMode() != GameMode.CREATIVE && player.getLocation().subtract(0.0, 1.0, 0.0).getBlock().getType() != Material.AIR && !player.isFlying()) { + player.setAllowFlight(true); + } + } + + @EventHandler + public void onFallDamage(final EntityDamageEvent e) { + if (e.getEntity() instanceof Player && e.getCause() == EntityDamageEvent.DamageCause.FALL) { + e.setCancelled(true); + } + } + + @EventHandler + public void onVoidDamage(final EntityDamageEvent e) { + if (e.getEntity() instanceof Player && e.getCause() == EntityDamageEvent.DamageCause.VOID) { + Player p = (Player) e; + + e.setCancelled(true); + p.teleport(p.getWorld().getSpawnLocation()); + } + } + + @EventHandler + public void move(final PlayerMoveEvent e) { + final Player f = e.getPlayer(); + if (e.getTo().getY() < 2.0) { + SnakeHub.getInst().getServer().getScheduler().scheduleSyncDelayedTask((Plugin) SnakeHub.getInst(), (Runnable)new Runnable() { + @Override + public void run() { + final double y = f.getLocation().getY() - 2.0; + final Location l = new Location(f.getLocation().getWorld(), f.getLocation().getX(), y, f.getLocation().getZ(), f.getLocation().getYaw(), f.getLocation().getPitch()); + f.getWorld().playEffect(l, Effect.ENDER_SIGNAL, 50, 30); + } + }, 10L); + } + } +} + diff --git a/src/main/java/dev/aapy/listeners/LaunchPadListener.java b/src/main/java/dev/aapy/listeners/LaunchPadListener.java new file mode 100644 index 0000000..50a7817 --- /dev/null +++ b/src/main/java/dev/aapy/listeners/LaunchPadListener.java @@ -0,0 +1,31 @@ +package dev.aapy.listeners; + +import dev.aapy.file.Config; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerMoveEvent; +import org.bukkit.util.Vector; + +/** + * @author 7qv_ on 17/2/2022. + * @project SnakeHub + */ +public class LaunchPadListener implements Listener { + + @EventHandler + public void onUseLaunch(PlayerMoveEvent event) { + Player p = event.getPlayer(); + if (p.getLocation().getBlock().getType() == Material.getMaterial(Config.getConfig().getString("LAUNCH-PAD.MATERIAL"))) { + Vector vector = p.getLocation().getDirection().multiply(2.0).setY(1.0); + p.setVelocity(vector); + + p.playSound(p.getLocation(), Sound.valueOf(Config.getConfig().getString("LAUNCH-PAD.SOUND")), 2.0f, 2.0f); + + } + + + } +} diff --git a/src/main/java/dev/aapy/listeners/LunarListener.java b/src/main/java/dev/aapy/listeners/LunarListener.java new file mode 100644 index 0000000..9dee20b --- /dev/null +++ b/src/main/java/dev/aapy/listeners/LunarListener.java @@ -0,0 +1,44 @@ +package dev.aapy.listeners; + +import com.lunarclient.bukkitapi.LunarClientAPI; +import dev.aapy.SnakeHub; +import dev.aapy.util.CC; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.plugin.Plugin; +import org.bukkit.scheduler.BukkitScheduler; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author 7qv_ on 9/2/2022. + * @project SnakeHub + */ +public class LunarListener implements Listener { + + public void updateNameTag( Player player) { + for (Player onlinePlayer : Bukkit.getOnlinePlayers()) { + BukkitScheduler scheduler = Bukkit.getServer().getScheduler(); + Player player2 = onlinePlayer.getPlayer(); + scheduler.scheduleSyncRepeatingTask((Plugin) SnakeHub.getInst(), () -> LunarClientAPI.getInstance().overrideNametag(player2, (List)this.resetNameTag(player2), player), 0L, 20L); + } + } + + public List resetNameTag(Player player) { + List tag = new ArrayList(); { + tag.add(CC.translate(SnakeHub.getInst().getPermission().getPermission().getPrefix(player))); + } + tag.add(CC.translate(SnakeHub.getInst().getPermission().getPermission().getPrefix(player) + player.getName())); + return tag; + } + + @EventHandler + public void onJoin(PlayerJoinEvent event) { + Player player = event.getPlayer(); + this.updateNameTag(player); + } +} \ No newline at end of file diff --git a/src/main/java/dev/aapy/listeners/PlayerListener.java b/src/main/java/dev/aapy/listeners/PlayerListener.java new file mode 100644 index 0000000..b1193f3 --- /dev/null +++ b/src/main/java/dev/aapy/listeners/PlayerListener.java @@ -0,0 +1,92 @@ +package dev.aapy.listeners; + +import com.lunarclient.bukkitapi.LunarClientAPI; +import com.lunarclient.bukkitapi.nethandler.client.LCPacketTitle; +import dev.aapy.SnakeHub; +import dev.aapy.file.Config; +import dev.aapy.file.Message; +import dev.aapy.util.CC; +import dev.aapy.util.ArmorCreator; +import me.activated.core.plugin.AquaCoreAPI; +import me.clip.placeholderapi.PlaceholderAPI; +import org.bukkit.*; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.EntityDamageEvent; +import org.bukkit.event.entity.FoodLevelChangeEvent; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.event.player.PlayerQuitEvent; + +import java.util.concurrent.TimeUnit; + +/** + * @author 7qv_ on 7/2/2022. + * @project SnakeHub + */ +public class PlayerListener implements Listener { + + @EventHandler + public void onJoin(PlayerJoinEvent event) { + Player p = event.getPlayer(); + event.setJoinMessage(null); + + p.setHealth(20); + p.setFoodLevel(20); + p.getInventory().setHelmet(new ArmorCreator(Material.LEATHER_HELMET).setColor(Color.AQUA).create()); + p.getInventory().setChestplate(new ArmorCreator(Material.LEATHER_CHESTPLATE).setColor(Color.AQUA).create()); + p.getInventory().setLeggings(new ArmorCreator(Material.LEATHER_LEGGINGS).setColor(Color.AQUA).create()); + p.getInventory().setBoots(new ArmorCreator(Material.LEATHER_BOOTS).setColor(Color.AQUA).create()); + p.playSound(p.getLocation(), Sound.WITHER_SPAWN, 1F, 1F); + // MESSAGE + if (Message.getConfig().getBoolean("TITLE.ENABLED")) { + LunarClientAPI.getInstance().sendPacket(p, new LCPacketTitle("TITLE", CC.translate(PlaceholderAPI.setPlaceholders(p, Message.getConfig().getString("TITLE.JOIN.TITLE.MESSAGE"))), TimeUnit.MILLISECONDS.toSeconds(10), TimeUnit.MILLISECONDS.toSeconds(10), TimeUnit.MILLISECONDS.toSeconds(10))); + LunarClientAPI.getInstance().sendPacket(p, new LCPacketTitle("SUBTITLE", CC.translate(PlaceholderAPI.setPlaceholders(p, Message.getConfig().getString("TITLE.JOIN.SUBTITLE.MESSAGE"))), TimeUnit.MILLISECONDS.toSeconds(10), TimeUnit.MILLISECONDS.toSeconds(10), TimeUnit.MILLISECONDS.toSeconds(10))); + } + if (Config.getConfig().getBoolean("BOOLEANS.JOIN-MESSAGE")) { + for (final String msg : Message.getConfig().getStringList("JOIN.MESSAGE")) { + p.sendMessage(CC.translate(msg) + .replace("{ign}", p.getName()) + .replace("{rank}", CC.translate(SnakeHub.getInst().getPermission().getPermission().getPrefix(p))) + .replace("{store}", CC.translate(Config.getConfig().getString("SOCIAL.STORE"))) + .replace("{team-speak}", CC.translate(Config.getConfig().getString("SOCIAL.TEAMSPEAK"))) + .replace("{twitter}", CC.translate(Config.getConfig().getString("SOCIAL.TWITTER"))) + .replace("{discord}", CC.translate(Config.getConfig().getString("SOCIAL.DISCORD"))) + .replace("{web-site}", CC.translate(Config.getConfig().getString("SOCIAL.WEBSITE")))); + } + } + } + + @EventHandler + public void onDamage(EntityDamageEvent event) { + if (event.getCause() == EntityDamageEvent.DamageCause.FALL) { + event.setCancelled(true); + } + } + + @EventHandler + public void onDisconect(PlayerQuitEvent event) { + Player p = event.getPlayer(); + event.setQuitMessage(null); + p.getInventory().clear(); + + if (Config.getConfig().getBoolean("BOOLEANS.QUIT-MESSAGE")) { + for (final String msg : Message.getConfig().getStringList("QUIT.MESSAGE")) { + p.sendMessage(CC.translate(msg) + .replace("{ign}", p.getName()) + .replace("{rank}", CC.translate(AquaCoreAPI.INSTANCE.getPlayerRank(p.getUniqueId()).getColor().toString() + AquaCoreAPI.INSTANCE.getPlayerRank(p.getUniqueId()).getPrefix().toString()))); + } + } + } + + @EventHandler + public void onFoodChange(FoodLevelChangeEvent event) { + if (event.getEntityType() == EntityType.PLAYER) { + Player p = (Player) event.getEntity(); + event.setCancelled(true); + if (p.getFoodLevel() < 19.0) + p.setFoodLevel(20); + } + } +} \ No newline at end of file diff --git a/src/main/java/dev/aapy/listeners/WorldListener.java b/src/main/java/dev/aapy/listeners/WorldListener.java new file mode 100644 index 0000000..fda1e94 --- /dev/null +++ b/src/main/java/dev/aapy/listeners/WorldListener.java @@ -0,0 +1,83 @@ +package dev.aapy.listeners; + +import dev.aapy.listeners.hotbar.PvPListener; +import org.bukkit.GameMode; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.block.BlockBreakEvent; +import org.bukkit.event.block.BlockPlaceEvent; +import org.bukkit.event.entity.CreatureSpawnEvent; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.event.entity.EntitySpawnEvent; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.player.PlayerDropItemEvent; + +/** + * @author 7qv_ on 7/2/2022. + * @project SnakeHub + */ +public class WorldListener implements Listener { + + @EventHandler + public void onSpawnMobs(CreatureSpawnEvent event) { + event.setCancelled(true); + } + + @EventHandler + public void onBreak(BlockBreakEvent event) { + Player p = event.getPlayer(); + if (p.hasPermission("hub.build")) { + event.setCancelled(false); + } else { + event.setCancelled(true); + } + } + + @EventHandler + public void onDropItems(PlayerDropItemEvent event) { + event.setCancelled(true); + } + + @EventHandler + public void onSpawn(EntitySpawnEvent event) { + event.setCancelled(true); + } + + @EventHandler + public void onPvP(EntityDamageByEntityEvent event) { + if (event.getDamager() instanceof Player) { + if (event.getEntity() instanceof Player) { + + Player damaged = (Player) event.getEntity(); + Player damager = (Player) event.getDamager(); + + if (PvPListener.pvpEnable.contains(damaged) && PvPListener.pvpEnable.contains(damager)) { + event.setCancelled(false); + } else { + event.setCancelled(true); + } + } + } + } + + @EventHandler + public void onClickInventory(InventoryClickEvent event) { + if (event.getWhoClicked().getGameMode().equals((Object) GameMode.CREATIVE)) { + event.setCancelled(false); + return; + } + event.setCancelled(true); + } + + + @EventHandler + public void onPlace(BlockPlaceEvent event) { + Player p = event.getPlayer(); + if (p.hasPermission("hub.build")) { + event.setCancelled(false); + } else { + event.setCancelled(true); + } + } +} diff --git a/src/main/java/dev/aapy/listeners/hotbar/CosmeticListener.java b/src/main/java/dev/aapy/listeners/hotbar/CosmeticListener.java new file mode 100644 index 0000000..98f81eb --- /dev/null +++ b/src/main/java/dev/aapy/listeners/hotbar/CosmeticListener.java @@ -0,0 +1,143 @@ +package dev.aapy.listeners.hotbar; + +import dev.aapy.file.Config; +import dev.aapy.listeners.hotbar.particles.Particles; +import dev.aapy.util.ArmorCreator; +import dev.aapy.util.ItemCreator; +import dev.aapy.util.CC; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.block.Action; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * @author 7qv_ on 15/2/2022. + * @project SnakeHub + */ +public class CosmeticListener implements Listener { + +@EventHandler + public void onJoin(PlayerJoinEvent event) { + Player p = event.getPlayer(); + + ItemStack hubmenu = new ItemStack(Material.getMaterial(Config.getConfig().getString("COSMETIC.MATERIAL"))); + ItemMeta hubmeta = hubmenu.getItemMeta(); + hubmeta.setDisplayName(CC.translate(Config.getConfig().getString("COSMETIC.DISPLAYNAME"))); + ArrayList lore = new ArrayList<>(); + lore.add(CC.translate(Config.getConfig().getString("COSMETIC.LORE"))); + hubmeta.addEnchant(Enchantment.DURABILITY, 3, Config.getConfig().getBoolean("COSMETIC.ENCHANTED")); + hubmeta.setLore(lore); + hubmenu.setItemMeta(hubmeta); + if (Config.getConfig().getBoolean("COSMETIC.ENABLED")) { + p.getInventory().setItem(Config.getConfig().getInt("COSMETIC.SLOT"), hubmenu); + } + } + + + public void CosmeticInventory(Player p) { + Inventory inv = Bukkit.createInventory(null, 9 * 3, CC.translate("&cCosmetic Menu")); + List armors = Arrays.asList("", "&7Change your outfit", "", "&aClick to view outfits"); + List armorsno = Arrays.asList("", "&7Change your outfit", "", "&aClick to view outfits", Config.getConfig().getString("SOCIAL.STORE")); + + List hats = Arrays.asList("", "&7Change your tag", "", "&aClick to view tags"); + List hatsno = Arrays.asList("", "&7Change your tag", "", "&aClick to view tags", Config.getConfig().getString("SOCIAL.STORE")); + + List Particles = Arrays.asList("", "&7Change your particles", "", "&aClick to view particles"); + List Particlesno = Arrays.asList("", "&7Change your particles", "", "&aClick to view particles", Config.getConfig().getString("SOCIAL.STORE")); + + if (p.hasPermission("hub.admin") && p.hasPermission("hub.donator")) { + inv.setItem(16 - 1, new ItemCreator(Material.NAME_TAG).title("&cTags").lores(hats).build()); + } + else{ + inv.setItem(16 - 1, new ItemCreator(Material.NAME_TAG).title("&cTags").lores(hatsno).build()); + } + + if (p.hasPermission("hub.admin") && p.hasPermission("hub.donator")) { + inv.setItem(14 - 1, new ItemCreator(Material.DIAMOND_CHESTPLATE).title("&cArmors").lores(armors).build()); + }else{ + inv.setItem(14 - 1, new ItemCreator(Material.DIAMOND_CHESTPLATE).title("&cArmors").lores(armorsno).build()); + } + + if (p.hasPermission("hub.admin") && p.hasPermission("hub.donator")) { + inv.setItem(12 - 1, new ItemCreator(Material.BLAZE_POWDER).title("&cParticles").lores(Particles).build()); + }else{ + inv.setItem(12 - 1, new ItemCreator(Material.BLAZE_POWDER).title("&cParticles").lores(Particlesno).build()); + } + + if (Config.getConfig().getBoolean("COSMETIC.GLASS_PANEL.ENABLED")) { + ItemStack panel = new ArmorCreator(Material.STAINED_GLASS_PANE, 1, (short) Config.getConfig().getInt("COSMETIC.GLASS_PANEL.ID")).setName("").build(); + + for (int i = 0; i < inv.getSize(); i++) { + if (inv.getItem(i) == null) { + inv.setItem(i, panel); + } + } + + } + + p.openInventory(inv); + } + + + @EventHandler + public void onInteract(PlayerInteractEvent event) { + if (event.getAction().equals((Object) Action.RIGHT_CLICK_AIR) || event.getAction().equals((Object) Action.RIGHT_CLICK_BLOCK)) { + Player player = event.getPlayer(); + if (player.getItemInHand().getType() == Material.EMERALD) { + this.CosmeticInventory(player); + } + } + } + + @EventHandler + public void onClickInventory(InventoryClickEvent event) { + Player player = (Player) event.getWhoClicked(); + ItemStack item = event.getCurrentItem(); + if (event.getCurrentItem() == null || event.getCurrentItem().getType() == Material.AIR || !event.getCurrentItem().hasItemMeta()) { + return; + } + if (event.getCurrentItem().getItemMeta() == null) { + return; + } + if (event.getClickedInventory().getTitle().equalsIgnoreCase(CC.translate("&cCosmetic Menu"))) { + if (event.getSlot() == 14 - 1) { + if(player.hasPermission("hub.donator")){ + OutfitsListener.OutfitInv(player); + event.setCancelled(true); + }else{ + player.closeInventory(); + player.sendMessage(CC.translate(Config.getConfig().getString("SOCIAL.STORE"))); + } + } else if (event.getSlot() == 12 - 1) { + if(player.hasPermission("hub.donator")){ + Particles.ParticleInv(player); + event.setCancelled(true); + }else{ + player.closeInventory(); + player.sendMessage(CC.translate(Config.getConfig().getString("SOCIAL.STORE"))); + } + } else if (event.getSlot() == 16 - 1) { + if(player.hasPermission("hub.donator")){ + player.performCommand("tags"); + event.setCancelled(true); + }else{ + player.closeInventory(); + player.sendMessage(CC.translate(Config.getConfig().getString("SOCIAL.STORE"))); + } + } + } + } +} \ No newline at end of file diff --git a/src/main/java/dev/aapy/listeners/hotbar/EnderButtListener.java b/src/main/java/dev/aapy/listeners/hotbar/EnderButtListener.java new file mode 100644 index 0000000..9ca3297 --- /dev/null +++ b/src/main/java/dev/aapy/listeners/hotbar/EnderButtListener.java @@ -0,0 +1,67 @@ +package dev.aapy.listeners.hotbar; + +import dev.aapy.file.Config; +import dev.aapy.util.CC; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.entity.Player; +import org.bukkit.event.Event; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.block.Action; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +import java.util.ArrayList; + +/** + * @author 7qv_ on 7/2/2022. + * @project SnakeHub + */ +public class EnderButtListener implements Listener { + + @EventHandler + public void onJoin(PlayerJoinEvent event) { + Player p = event.getPlayer(); + + ItemStack enderbutt = new ItemStack(Material.getMaterial(Config.getConfig().getString("ENDERBUTT.MATERIAL"))); + ItemMeta endermeta = enderbutt.getItemMeta(); + endermeta.setDisplayName(CC.translate(Config.getConfig().getString("ENDERBUTT.DISPLAYNAME"))); + ArrayList lore = new ArrayList<>(); + lore.add(CC.translate(Config.getConfig().getString("ENDERBUTT.LORE"))); + endermeta.addEnchant(Enchantment.DURABILITY, 3, Config.getConfig().getBoolean("ENDERBUTT.ENCHANTED")); + endermeta.setLore(lore); + enderbutt.setItemMeta(endermeta); + if (Config.getConfig().getBoolean("ENDERBUTT.ENABLED")) { + p.getInventory().setItem(Config.getConfig().getInt("ENDERBUTT.SLOT"), enderbutt); + } + } + + + @EventHandler + public void onInteract(PlayerInteractEvent event) { + if (event.hasItem()) { + if (event.getAction() == Action.RIGHT_CLICK_AIR || event.getAction() == Action.RIGHT_CLICK_BLOCK) { + if (event.getItem().getItemMeta() == null) { + return; + } + if (event.getItem().getItemMeta().getDisplayName() == null) { + return; + } + if (event.getItem().getItemMeta().getDisplayName().equalsIgnoreCase(CC.translate(Config.getConfig().getString("ENDERBUTT.DISPLAYNAME")))) { + event.getPlayer().setVelocity(event.getPlayer().getLocation().getDirection().multiply(2.5F)); + + event.setCancelled(true); + event.setUseItemInHand(Event.Result.DENY); + + event.getPlayer().updateInventory(); + + event.getPlayer().playSound(event.getPlayer().getLocation(), Sound.valueOf(Config.getConfig().getString("ENDERBUTT.SOUND")), 2.0f, 2.0f); + } + } + } + } +} diff --git a/src/main/java/dev/aapy/listeners/hotbar/OutfitsListener.java b/src/main/java/dev/aapy/listeners/hotbar/OutfitsListener.java new file mode 100644 index 0000000..a4fde77 --- /dev/null +++ b/src/main/java/dev/aapy/listeners/hotbar/OutfitsListener.java @@ -0,0 +1,331 @@ +package dev.aapy.listeners.hotbar; + +import dev.aapy.file.Config; +import dev.aapy.util.CC; +import dev.aapy.util.ItemCreator; +import org.bukkit.Bukkit; +import org.bukkit.Color; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; + +import java.util.Arrays; +import java.util.List; + +/** + * @author 7qv_ on 18/2/2022. + * @project SnakeHub + */ +public class OutfitsListener implements Listener { + + public static void OutfitInv(Player p) { + Inventory inv = Bukkit.createInventory(null, 9 * 2, CC.translate("&6Outfit Menu")); + List lore = Arrays.asList("","&6Click to select Outfit",""); + List clearlore = Arrays.asList("","&7Click to Clear Outfits",""); + + inv.setItem(1 - 1, new ItemCreator(Material.LEATHER_HELMET).title("&eBlack Outfit").lores(lore).color(convert("0")).build()); + inv.setItem(2 - 1, new ItemCreator(Material.LEATHER_HELMET).title("&eBlue Outfit").lores(lore).color(convert("1")).build()); + inv.setItem(3 - 1, new ItemCreator(Material.LEATHER_HELMET).title("&eGreen Outfit").lores(lore).color(convert("2")).build()); + inv.setItem(4 - 1, new ItemCreator(Material.LEATHER_HELMET).title("&eCyan Outfit").lores(lore).color(convert("3")).build()); + inv.setItem(5 - 1, new ItemCreator(Material.LEATHER_HELMET).title("&eRed Outfit").lores(lore).color(convert("4")).build()); + inv.setItem(6 - 1, new ItemCreator(Material.LEATHER_HELMET).title("&ePurple Outfit").lores(lore).color(convert("5")).build()); + inv.setItem(7 - 1, new ItemCreator(Material.LEATHER_HELMET).title("&eOrange Outfit").lores(lore).color(convert("6")).build()); + inv.setItem(8 - 1, new ItemCreator(Material.LEATHER_HELMET).title("&eSilver Outfit").lores(lore).color(convert("7")).build()); + inv.setItem(9 - 1, new ItemCreator(Material.LEATHER_HELMET).title("&eGray Outfit").lores(lore).color(convert("8")).build()); + inv.setItem(10 - 1, new ItemCreator(Material.LEATHER_HELMET).title("&eLime Outfit").lores(lore).color(convert("a")).build()); + inv.setItem(11 - 1, new ItemCreator(Material.LEATHER_HELMET).title("&eYellow Outfit").lores(lore).color(convert("e")).build()); + inv.setItem(12 - 1, new ItemCreator(Material.LEATHER_HELMET).title("&eAqua Outfit").lores(lore).color(convert("b")).build()); + inv.setItem(13 - 1, new ItemCreator(Material.LEATHER_HELMET).title("&eFuchsia Outfit").lores(lore).color(convert("d")).build()); + inv.setItem(14 - 1, new ItemCreator(Material.LEATHER_HELMET).title("&eWhite Outfit").lores(lore).color(convert("f")).build()); + + if (p.hasPermission("hub.admin") && p.hasPermission("hub.donator")) { + inv.setItem(18 - 1, new ItemCreator(Material.FEATHER).title("&cClear Outfit!").lores(clearlore).build()); + } + p.openInventory(inv); + } + @EventHandler + public void onClickInventory (InventoryClickEvent event) { + Player player = (Player) event.getWhoClicked(); + ItemStack item = event.getCurrentItem(); + if (event.getCurrentItem() == null || event.getCurrentItem().getType() == Material.AIR || !event.getCurrentItem().hasItemMeta()) { + return; + } + if (event.getCurrentItem().getItemMeta() == null) { + return; + } + if (event.getClickedInventory().getTitle().equalsIgnoreCase(CC.translate("&6Outfit Menu"))) { + if (player.hasPermission("hub.admin") && player.hasPermission("hub.donator")) { + if (event.getSlot() == 1 - 1) { + ItemStack blackh = new ItemCreator(Material.LEATHER_HELMET).color(OutfitsListener.convert("0")).build(); + ItemStack blackc = new ItemCreator(Material.LEATHER_CHESTPLATE).color(OutfitsListener.convert("0")).build(); + ItemStack blackl = new ItemCreator(Material.LEATHER_LEGGINGS).color(OutfitsListener.convert("0")).build(); + ItemStack blackb = new ItemCreator(Material.LEATHER_BOOTS).color(OutfitsListener.convert("0")).build(); + + player.getInventory().setHelmet(blackh); + player.getInventory().setChestplate(blackc); + player.getInventory().setLeggings(blackl); + player.getInventory().setBoots(blackb); + + player.sendMessage(CC.translate("&fYou has been change your Outfit at &6Black&f Outfit!")); + player.closeInventory(); + event.setCancelled(true); + } else if (event.getSlot() == 2 - 1) { + ItemStack blueh = new ItemCreator(Material.LEATHER_HELMET).color(OutfitsListener.convert("1")).build(); + ItemStack bluec = new ItemCreator(Material.LEATHER_CHESTPLATE).color(OutfitsListener.convert("1")).build(); + ItemStack bluel = new ItemCreator(Material.LEATHER_LEGGINGS).color(OutfitsListener.convert("1")).build(); + ItemStack blueb = new ItemCreator(Material.LEATHER_BOOTS).color(OutfitsListener.convert("1")).build(); + + player.getInventory().setHelmet(blueh); + player.getInventory().setChestplate(bluec); + player.getInventory().setLeggings(bluel); + player.getInventory().setBoots(blueb); + + player.sendMessage(CC.translate("&fYou has been change your Outfit at &6Blue&f Outfit!")); + player.closeInventory(); + event.setCancelled(true); + } else if (event.getSlot() == 3 - 1) { + ItemStack greenh = new ItemCreator(Material.LEATHER_HELMET).color(OutfitsListener.convert("2")).build(); + ItemStack greenc = new ItemCreator(Material.LEATHER_CHESTPLATE).color(OutfitsListener.convert("2")).build(); + ItemStack greenl = new ItemCreator(Material.LEATHER_LEGGINGS).color(OutfitsListener.convert("2")).build(); + ItemStack greenb = new ItemCreator(Material.LEATHER_BOOTS).color(OutfitsListener.convert("2")).build(); + + player.getInventory().setHelmet(greenh); + player.getInventory().setChestplate(greenc); + player.getInventory().setLeggings(greenl); + player.getInventory().setBoots(greenb); + player.sendMessage(CC.translate("&fYou has been change your Outfit at &6Green&f Outfit!")); + + player.closeInventory(); + event.setCancelled(true); + } else if (event.getSlot() == 4 - 1) { + ItemStack cyanh = new ItemCreator(Material.LEATHER_HELMET).color(OutfitsListener.convert("3")).build(); + ItemStack cyanc = new ItemCreator(Material.LEATHER_CHESTPLATE).color(OutfitsListener.convert("3")).build(); + ItemStack cyanl = new ItemCreator(Material.LEATHER_LEGGINGS).color(OutfitsListener.convert("3")).build(); + ItemStack cyanb = new ItemCreator(Material.LEATHER_BOOTS).color(OutfitsListener.convert("3")).build(); + + player.getInventory().setHelmet(cyanh); + player.getInventory().setChestplate(cyanc); + player.getInventory().setLeggings(cyanl); + player.getInventory().setBoots(cyanb); + player.sendMessage(CC.translate("&fYou has been change your Outfit at &6Cyan&f Outfit!")); + + player.closeInventory(); + event.setCancelled(true); + } else if (event.getSlot() == 5 - 1) { + ItemStack armor = new ItemCreator(Material.LEATHER_HELMET).color(OutfitsListener.convert("4")).build(); + ItemStack armor1 = new ItemCreator(Material.LEATHER_CHESTPLATE).color(OutfitsListener.convert("4")).build(); + ItemStack armor2 = new ItemCreator(Material.LEATHER_LEGGINGS).color(OutfitsListener.convert("4")).build(); + ItemStack armor3 = new ItemCreator(Material.LEATHER_BOOTS).color(OutfitsListener.convert("4")).build(); + + player.getInventory().setHelmet(armor); + player.getInventory().setChestplate(armor1); + player.getInventory().setLeggings(armor2); + player.getInventory().setBoots(armor3); + player.sendMessage(CC.translate("&fYou has been change your Outfit at &6Red&f Outfit!")); + + player.closeInventory(); + event.setCancelled(true); + } else if (event.getSlot() == 6 - 1) { + ItemStack armor = new ItemCreator(Material.LEATHER_HELMET).color(OutfitsListener.convert("5")).build(); + ItemStack armor1 = new ItemCreator(Material.LEATHER_CHESTPLATE).color(OutfitsListener.convert("5")).build(); + ItemStack armor2 = new ItemCreator(Material.LEATHER_LEGGINGS).color(OutfitsListener.convert("5")).build(); + ItemStack armor3 = new ItemCreator(Material.LEATHER_BOOTS).color(OutfitsListener.convert("5")).build(); + + player.getInventory().setHelmet(armor); + player.getInventory().setChestplate(armor1); + player.getInventory().setLeggings(armor2); + player.getInventory().setBoots(armor3); + player.sendMessage(CC.translate("&fYou has been change your Outfit at &6Purple&f Outfit!")); + + player.closeInventory(); + event.setCancelled(true); + } else if (event.getSlot() == 7 - 1) { + ItemStack armor = new ItemCreator(Material.LEATHER_HELMET).color(OutfitsListener.convert("6")).build(); + ItemStack armor1 = new ItemCreator(Material.LEATHER_CHESTPLATE).color(OutfitsListener.convert("6")).build(); + ItemStack armor2 = new ItemCreator(Material.LEATHER_LEGGINGS).color(OutfitsListener.convert("6")).build(); + ItemStack armor3 = new ItemCreator(Material.LEATHER_BOOTS).color(OutfitsListener.convert("6")).build(); + + player.getInventory().setHelmet(armor); + player.getInventory().setChestplate(armor1); + player.getInventory().setLeggings(armor2); + player.getInventory().setBoots(armor3); + player.sendMessage(CC.translate("&fYou has been change your Outfit at &6Orange&f Outfit!")); + + player.closeInventory(); + event.setCancelled(true); + } else if (event.getSlot() == 8 - 1) { + ItemStack armor = new ItemCreator(Material.LEATHER_HELMET).color(OutfitsListener.convert("7")).build(); + ItemStack armor1 = new ItemCreator(Material.LEATHER_CHESTPLATE).color(OutfitsListener.convert("7")).build(); + ItemStack armor2 = new ItemCreator(Material.LEATHER_LEGGINGS).color(OutfitsListener.convert("7")).build(); + ItemStack armor3 = new ItemCreator(Material.LEATHER_BOOTS).color(OutfitsListener.convert("7")).build(); + + player.getInventory().setHelmet(armor); + player.getInventory().setChestplate(armor1); + player.getInventory().setLeggings(armor2); + player.getInventory().setBoots(armor3); + + player.sendMessage(CC.translate("&fYou has been change your Outfit at &6Silver&f Outfit!")); + + player.closeInventory(); + event.setCancelled(true); + } else if (event.getSlot() == 9 - 1) { + ItemStack armor = new ItemCreator(Material.LEATHER_HELMET).color(OutfitsListener.convert("8")).build(); + ItemStack armor1 = new ItemCreator(Material.LEATHER_CHESTPLATE).color(OutfitsListener.convert("8")).build(); + ItemStack armor2 = new ItemCreator(Material.LEATHER_LEGGINGS).color(OutfitsListener.convert("8")).build(); + ItemStack armor3 = new ItemCreator(Material.LEATHER_BOOTS).color(OutfitsListener.convert("8")).build(); + + player.getInventory().setHelmet(armor); + player.getInventory().setChestplate(armor1); + player.getInventory().setLeggings(armor2); + player.getInventory().setBoots(armor3); + player.sendMessage(CC.translate("&fYou has been change your Outfit at &6Gray&f Outfit!")); + + player.closeInventory(); + event.setCancelled(true); + } else if (event.getSlot() == 10 - 1) { + ItemStack armor = new ItemCreator(Material.LEATHER_HELMET).color(OutfitsListener.convert("a")).build(); + ItemStack armor1 = new ItemCreator(Material.LEATHER_CHESTPLATE).color(OutfitsListener.convert("a")).build(); + ItemStack armor2 = new ItemCreator(Material.LEATHER_LEGGINGS).color(OutfitsListener.convert("a")).build(); + ItemStack armor3 = new ItemCreator(Material.LEATHER_BOOTS).color(OutfitsListener.convert("a")).build(); + + player.getInventory().setHelmet(armor); + player.getInventory().setChestplate(armor1); + player.getInventory().setLeggings(armor2); + player.getInventory().setBoots(armor3); + player.sendMessage(CC.translate("&fYou has been change your Outfit at &6Lime&f Outfit!")); + + player.closeInventory(); + event.setCancelled(true); + } else if (event.getSlot() == 11 - 1) { + ItemStack armor = new ItemCreator(Material.LEATHER_HELMET).color(OutfitsListener.convert("e")).build(); + ItemStack armor1 = new ItemCreator(Material.LEATHER_CHESTPLATE).color(OutfitsListener.convert("e")).build(); + ItemStack armor2 = new ItemCreator(Material.LEATHER_LEGGINGS).color(OutfitsListener.convert("e")).build(); + ItemStack armor3 = new ItemCreator(Material.LEATHER_BOOTS).color(OutfitsListener.convert("e")).build(); + + player.getInventory().setHelmet(armor); + player.getInventory().setChestplate(armor1); + player.getInventory().setLeggings(armor2); + player.getInventory().setBoots(armor3); + player.sendMessage(CC.translate("&fYou has been change your Outfit at &6Yellow&f Outfit!")); + + player.closeInventory(); + event.setCancelled(true); + } else if (event.getSlot() == 12 - 1) { + ItemStack armor = new ItemCreator(Material.LEATHER_HELMET).color(OutfitsListener.convert("b")).build(); + ItemStack armor1 = new ItemCreator(Material.LEATHER_CHESTPLATE).color(OutfitsListener.convert("b")).build(); + ItemStack armor2 = new ItemCreator(Material.LEATHER_LEGGINGS).color(OutfitsListener.convert("b")).build(); + ItemStack armor3 = new ItemCreator(Material.LEATHER_BOOTS).color(OutfitsListener.convert("b")).build(); + + player.getInventory().setHelmet(armor); + player.getInventory().setChestplate(armor1); + player.getInventory().setLeggings(armor2); + player.getInventory().setBoots(armor3); + + player.sendMessage(CC.translate("&fYou has been change your Outfit at &6Aqua&f Outfit!")); + + player.closeInventory(); + event.setCancelled(true); + } else if (event.getSlot() == 13 - 1) { + ItemStack armor = new ItemCreator(Material.LEATHER_HELMET).color(OutfitsListener.convert("d")).build(); + ItemStack armor1 = new ItemCreator(Material.LEATHER_CHESTPLATE).color(OutfitsListener.convert("d")).build(); + ItemStack armor2 = new ItemCreator(Material.LEATHER_LEGGINGS).color(OutfitsListener.convert("d")).build(); + ItemStack armor3 = new ItemCreator(Material.LEATHER_BOOTS).color(OutfitsListener.convert("d")).build(); + + player.getInventory().setHelmet(armor); + player.getInventory().setChestplate(armor1); + player.getInventory().setLeggings(armor2); + player.getInventory().setBoots(armor3); + player.sendMessage(CC.translate("&fYou has been change your Outfit at &6Fuchsia&f Outfit!")); + + player.closeInventory(); + event.setCancelled(true); + } else if (event.getSlot() == 14 - 1) { + ItemStack armor = new ItemCreator(Material.LEATHER_HELMET).color(OutfitsListener.convert("f")).build(); + ItemStack armor1 = new ItemCreator(Material.LEATHER_CHESTPLATE).color(OutfitsListener.convert("f")).build(); + ItemStack armor2 = new ItemCreator(Material.LEATHER_LEGGINGS).color(OutfitsListener.convert("f")).build(); + ItemStack armor3 = new ItemCreator(Material.LEATHER_BOOTS).color(OutfitsListener.convert("f")).build(); + + player.getInventory().setHelmet(armor); + player.getInventory().setChestplate(armor1); + player.getInventory().setLeggings(armor2); + player.getInventory().setBoots(armor3); + player.sendMessage(CC.translate("&fYou has been change your Outfit at &6White&f Outfit!")); + + player.closeInventory(); + event.setCancelled(true); + } else if (event.getSlot() == 18 - 1) { + if (player.getInventory().getHelmet() == null) { + player.sendMessage(CC.translate("&cYou do not have any Outfit available, buy them at store.serpentmc.club")); + player.closeInventory(); + event.setCancelled(true); + } else { + player.getInventory().setHelmet(null); + player.getInventory().setChestplate(null); + player.getInventory().setLeggings(null); + player.getInventory().setBoots(null); + player.sendMessage(CC.translate("&cYou have taken off your outfits, put them back on to look cooler!")); + + player.closeInventory(); + event.setCancelled(true); + } + } + } else { + player.sendMessage(CC.translate(Config.getConfig().getString("SOCIAL.STORE"))); + player.closeInventory(); + event.setCancelled(true); + } + } + } + public static Color convert(String colorString) { + if (colorString.contains("0")) { + return Color.BLACK; + } + if (colorString.contains("1")) { + return Color.BLUE; + } + if (colorString.contains("2")) { + return Color.GREEN; + } + if (colorString.contains("3")) { + return Color.TEAL; + } + if (colorString.contains("4")) { + return Color.RED; + } + if (colorString.contains("5")) { + return Color.PURPLE; + } + if (colorString.contains("6")) { + return Color.ORANGE; + } + if (colorString.contains("7")) { + return Color.SILVER; + } + if (colorString.contains("8")) { + return Color.GRAY; + } + if (colorString.contains("9")) { + return Color.BLUE; + } + if (colorString.contains("a")) { + return Color.LIME; + } + if (colorString.contains("e")) { + return Color.YELLOW; + } + if (colorString.contains("b")) { + return Color.AQUA; + } + if (colorString.contains("d")) { + return Color.FUCHSIA; + } + if (colorString.contains("f")) { + return Color.WHITE; + } + return Color.BLACK; + } +} diff --git a/src/main/java/dev/aapy/listeners/hotbar/PlayerInvisibilityListener.java b/src/main/java/dev/aapy/listeners/hotbar/PlayerInvisibilityListener.java new file mode 100644 index 0000000..9fb8e93 --- /dev/null +++ b/src/main/java/dev/aapy/listeners/hotbar/PlayerInvisibilityListener.java @@ -0,0 +1,94 @@ +package dev.aapy.listeners.hotbar; + +import dev.aapy.file.Config; +import dev.aapy.file.Message; +import dev.aapy.util.CC; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.block.Action; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +import java.util.Iterator; + +/** + * @author 7qv_ on 14/3/2022. + * @project SnakeHub + */ +public class PlayerInvisibilityListener implements Listener { + + + @EventHandler + public void onJoin(PlayerJoinEvent event) { + Player p = event.getPlayer(); + addItem(p); + } + + public void addItem(Player p) { + if (Config.getConfig().getBoolean("INVISIBILITY.ENABLED")) { + p.getInventory().setItem(Config.getConfig().getInt("INVISIBILITY.ITEM.SHOW-PLAYER.SLOT"), ShowPlayer()); + } + } + + public static ItemStack ShowPlayer() { + ItemStack shows = new ItemStack(Material.getMaterial(Config.getConfig().getString("INVISIBILITY.ITEM.SHOW-PLAYER.MATERIAL"))); + ItemMeta showsm = shows.getItemMeta(); + showsm.setDisplayName(CC.translate(Config.getConfig().getString("INVISIBILITY.ITEM.SHOW-PLAYER.NAME"))); + shows.setItemMeta(showsm); + return shows; + } + + public static ItemStack HidePlayer() { + ItemStack hides = new ItemStack(Material.getMaterial(Config.getConfig().getString("INVISIBILITY.ITEM.HIDE-PLAYER.MATERIAL"))); + ItemMeta hidesm = hides.getItemMeta(); + hidesm.setDisplayName(CC.translate(Config.getConfig().getString("INVISIBILITY.ITEM.HIDE-PLAYER.NAME"))); + hides.setItemMeta(hidesm); + return hides; + } + + @EventHandler(priority = EventPriority.MONITOR) + public void onInvis(final PlayerInteractEvent event) { + Player player = event.getPlayer(); + ItemStack stack = player.getItemInHand(); + if (event.getAction() == Action.RIGHT_CLICK_BLOCK || event.getAction() == Action.RIGHT_CLICK_AIR) { + Iterator iterator; + Player player1; + if (stack != null && stack.isSimilar(HidePlayer())) { + event.setCancelled(true); + iterator = Bukkit.getServer().getOnlinePlayers().iterator(); + + while (iterator.hasNext()) { + player1 = (Player) iterator.next(); + player.hidePlayer(player1); + } + + player.setItemInHand(ShowPlayer()); + player.updateInventory(); + player.playSound(player.getLocation(), Sound.CLICK, 1.0F, 1.0F); + player.sendMessage(CC.translate(Message.getConfig().getString("HIDE-PLAYER"))); + } + + if (stack != null && stack.isSimilar(ShowPlayer())) { + event.setCancelled(true); + iterator = Bukkit.getServer().getOnlinePlayers().iterator(); + + while (iterator.hasNext()) { + player1 = (Player) iterator.next(); + player.showPlayer(player1); + } + + player.setItemInHand(HidePlayer()); + player.updateInventory(); + player.playSound(player.getLocation(), Sound.CLICK, 1.0F, 1.0F); + player.sendMessage(CC.translate(Message.getConfig().getString("SHOW-PLAYER"))); + } + } + } +} \ No newline at end of file diff --git a/src/main/java/dev/aapy/listeners/hotbar/PvPListener.java b/src/main/java/dev/aapy/listeners/hotbar/PvPListener.java new file mode 100644 index 0000000..234d6d2 --- /dev/null +++ b/src/main/java/dev/aapy/listeners/hotbar/PvPListener.java @@ -0,0 +1,123 @@ +package dev.aapy.listeners.hotbar; + +import dev.aapy.file.Config; +import dev.aapy.util.CC; +import org.bukkit.Bukkit; +import org.bukkit.GameMode; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.block.Action; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; + +import java.util.ArrayList; + +/** + * @author 7qv_ on 21/2/2022. + * @propect SnakeHub + */ +public class PvPListener implements Listener { + + public static ArrayList pvpEnable = new ArrayList(); + + @EventHandler + public void onJoin(PlayerJoinEvent event) { + Player p = event.getPlayer(); + + ItemStack pvps = new ItemStack(Material.getMaterial(Config.getConfig().getString("PVP.MATERIAL"))); + ItemMeta pvpmeta = pvps.getItemMeta(); + pvpmeta.setDisplayName(CC.translate(Config.getConfig().getString("PVP.DISPLAYNAME"))); + ArrayList lore = new ArrayList<>(); + lore.add(CC.translate(Config.getConfig().getString("PVP.LORE"))); + pvpmeta.setLore(lore); + pvpmeta.addEnchant(Enchantment.DURABILITY, 3, Config.getConfig().getBoolean("PVP.ENCHANTED")); + pvps.setItemMeta(pvpmeta); + if (Config.getConfig().getBoolean("PVP.ENABLED")) { + p.getInventory().setItem(Config.getConfig().getInt("PVP.SLOT"), pvps); + } + } + + public static void enablePvPMode(Player p) { + p.setFireTicks(0); + for (PotionEffect effect : p.getActivePotionEffects()) { + p.removePotionEffect(effect.getType()); + } + + p.getInventory().clear(); + pvpEnable.add(p); + giveKitPvP((PlayerInteractEvent) p); + p.sendMessage(CC.translate("&aYou turned on your PvP-Mode and you can receive damage.")); + } + + @EventHandler + public void leaveGameInPvPMode(PlayerQuitEvent event) { + Player p = event.getPlayer(); + if (pvpEnable.contains(p)) { + pvpEnable.remove(p); + Bukkit.getConsoleSender().sendMessage(CC.translate("&cThe player " + p.getName() + " &chas " + + "left when your pvp-mode is enabled, and has been removed for minor bugs")); + } + } + + @EventHandler + public static void giveKitPvP(PlayerInteractEvent event) { + if (event.getAction() == Action.RIGHT_CLICK_AIR || event.getAction() == Action.RIGHT_CLICK_BLOCK) { + Player p = event.getPlayer(); + + if (p.getInventory().getItemInHand().getType() == Material.getMaterial(Config.getConfig().getString("PVP.MATERIAL"))) { + p.playSound(p.getLocation(), Sound.valueOf(Config.getConfig().getString("PVP.SOUND")), 2.0f, 2.0f); + + + p.getInventory().clear(); + if(p.getGameMode() == GameMode.CREATIVE){ + p.sendMessage(CC.translate("&cUps... You need change your gamemode after poin!.")); + return; + }else{ + + ItemStack he = new ItemStack(310, 1, (short)0); + ItemStack ch = new ItemStack(310, 1, (short)0); + ItemStack leg = new ItemStack(310, 1, (short)0); + ItemStack bo = new ItemStack(310, 1, (short)0); + ItemStack sword = new ItemStack(276, 1, (short)0); + ItemStack enderpearl = new ItemStack(368, 16, (short)0); + ItemStack steack = new ItemStack(364, 32, (short)0); + PotionEffect speed = new PotionEffect(PotionEffectType.SPEED, 99999, 1); + PotionEffect fireres = new PotionEffect(PotionEffectType.SPEED, 99999, 1); + + bo.addEnchantment(Enchantment.PROTECTION_ENVIRONMENTAL, 1); + ch.addEnchantment(Enchantment.PROTECTION_ENVIRONMENTAL, 1); + leg.addEnchantment(Enchantment.PROTECTION_ENVIRONMENTAL, 1); + bo.addEnchantment(Enchantment.PROTECTION_ENVIRONMENTAL, 1); + bo.addEnchantment(Enchantment.PROTECTION_ENVIRONMENTAL, 1); + sword.addEnchantment(Enchantment.DAMAGE_ALL, 1); + + + p.getInventory().setHelmet(he); + p.getInventory().setChestplate(ch); + p.getInventory().setLeggings(leg); + p.getInventory().setBoots(bo); + p.getInventory().setItem(0, sword); + p.getInventory().setItem(1, enderpearl); + p.getInventory().setItem(2, steack); + + p.addPotionEffect(speed); + p.addPotionEffect(fireres); + for (int i = 3; i < 34; i++) { + ItemStack healthPotions = new ItemStack(373, 1, (short)16421); + p.getInventory().setItem(i, healthPotions); + } + } + } + } + } +} diff --git a/src/main/java/dev/aapy/listeners/hotbar/SelectorListener.java b/src/main/java/dev/aapy/listeners/hotbar/SelectorListener.java new file mode 100644 index 0000000..c798bdb --- /dev/null +++ b/src/main/java/dev/aapy/listeners/hotbar/SelectorListener.java @@ -0,0 +1,145 @@ +package dev.aapy.listeners.hotbar; + +import dev.aapy.file.Config; +import dev.aapy.util.ArmorCreator; +import dev.aapy.util.CC; +import dev.aapy.util.bungee.BungeeChannel; +import me.clip.placeholderapi.PlaceholderAPI; +import me.signatured.ezqueuespigot.EzQueueAPI; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.block.Action; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +import java.util.ArrayList; + +/** + * @author 7qv_ on 16/2/2022. + * @project SnakeHub + */ +public class SelectorListener implements Listener { + @EventHandler + public void onJoin(PlayerJoinEvent event) { + Player player = event.getPlayer(); + ItemStack selectormenu = new ItemStack(Material.valueOf(Config.getConfig().getString("SELECTOR.MATERIAL"))); + ItemMeta selectormeta = selectormenu.getItemMeta(); + selectormeta.setDisplayName(CC.translate(Config.getConfig().getString("SELECTOR.DISPLAYNAME"))); + ArrayList lore = new ArrayList<>(); + lore.add(CC.translate(Config.getConfig().getString("SELECTOR.LORE"))); + selectormeta.setLore(lore); + if (Config.getConfig().getBoolean("SELECTOR.ENCHANTED")) + selectormeta.addEnchant(Enchantment.DURABILITY, 3, true); + selectormenu.setItemMeta(selectormeta); + if (Config.getConfig().getBoolean("SELECTOR.ENABLED")) + player.getInventory().setItem(Config.getConfig().getInt("SELECTOR.SLOT"), selectormenu); + } + + @EventHandler + public void onInteractSelector(PlayerInteractEvent event) { + if (event.getAction() == Action.RIGHT_CLICK_AIR || event.getAction() == Action.RIGHT_CLICK_BLOCK) { + Player player = event.getPlayer(); + if (player.getInventory().getItemInHand().getType() == Material.valueOf(Config.getConfig().getString("SELECTOR.MATERIAL"))) { + if (Config.getConfig().getBoolean("SELECTOR.SOUND_ENABLED")) + player.playSound(player.getLocation(), Sound.valueOf(Config.getConfig().getString("SELECTOR.SOUND")), 2.0F, 2.0F); + Inventory inv = Bukkit.createInventory(null, 27, CC.translate(Config.getConfig().getString("SELECTOR.TITLE"))); + ItemStack item = new ItemStack(Material.valueOf(Config.getConfig().getString("SELECTOR.SERVERS.1.MATERIAL"))); + ItemMeta meta = item.getItemMeta(); + meta.setDisplayName(CC.translate(Config.getConfig().getString("SELECTOR.SERVERS.1.DISPLAYNAME"))); + ArrayList lore = new ArrayList<>(); + lore.addAll(CC.translate(PlaceholderAPI.setPlaceholders(player, Config.getConfig().getStringList("SELECTOR.SERVERS.1.LORE")))); + if (Config.getConfig().getBoolean("SELECTOR.SERVERS.1.ENCHANTED")) + meta.addEnchant(Enchantment.DURABILITY, 3, true); + meta.setLore(lore); + item.setItemMeta(meta); + ItemStack item2 = new ItemStack(Material.valueOf(Config.getConfig().getString("SELECTOR.SERVERS.2.MATERIAL"))); + ItemMeta itemMeta1 = item2.getItemMeta(); + itemMeta1.setDisplayName(CC.translate(Config.getConfig().getString("SELECTOR.SERVERS.2.DISPLAYNAME"))); + ArrayList arrayList1 = new ArrayList<>(); + arrayList1.addAll(CC.translate(PlaceholderAPI.setPlaceholders(player, Config.getConfig().getStringList("SELECTOR.SERVERS.2.LORE")))); + if (Config.getConfig().getBoolean("SELECTOR.SERVERS.2.ENCHANTED")) + itemMeta1.addEnchant(Enchantment.DURABILITY, 3, true); + itemMeta1.setLore(arrayList1); + item2.setItemMeta(itemMeta1); + ItemStack item3 = new ItemStack(Material.valueOf(Config.getConfig().getString("SELECTOR.SERVERS.3.MATERIAL"))); + ItemMeta itemMeta2 = item3.getItemMeta(); + itemMeta2.setDisplayName(CC.translate(Config.getConfig().getString("SELECTOR.SERVERS.3.DISPLAYNAME"))); + ArrayList arrayList2 = new ArrayList<>(); + arrayList2.addAll(CC.translate(PlaceholderAPI.setPlaceholders(player, Config.getConfig().getStringList("SELECTOR.SERVERS.3.LORE")))); + if (Config.getConfig().getBoolean("SELECTOR.SERVERS.3.ENCHANTED")) + itemMeta2.addEnchant(Enchantment.DURABILITY, 3, true); + itemMeta2.setLore(arrayList2); + item3.setItemMeta(itemMeta2); + inv.setItem(Config.getConfig().getInt("SELECTOR.SERVERS.1.SLOT"), item); + inv.setItem(Config.getConfig().getInt("SELECTOR.SERVERS.2.SLOT"), item2); + inv.setItem(Config.getConfig().getInt("SELECTOR.SERVERS.3.SLOT"), item3); + if (Config.getConfig().getBoolean("SELECTOR.GLASS_PANEL.ENABLED")) { + ItemStack panel = (new ArmorCreator(Material.STAINED_GLASS_PANE, 1, (short)Config.getConfig().getInt("SELECTOR.GLASS_PANEL.ID"))).setName("").build(); + for (int i = 0; i < inv.getSize(); i++) { + if (inv.getItem(i) == null) + inv.setItem(i, panel); + } + } + if (player.isOnline()) + player.openInventory(inv); + } + } + } + + @EventHandler + public void onClickItemSelector(InventoryClickEvent event) { + Player player = (Player)event.getWhoClicked(); + if (event.getInventory().getName().equalsIgnoreCase(CC.translate(Config.getConfig().getString("SELECTOR.TITLE"))) && + event.getCurrentItem().getType() == Material.valueOf(Config.getConfig().getString("SELECTOR.SERVERS.1.MATERIAL"))) { + player.sendMessage(CC.translate(Config.getConfig().getString("SELECTOR.SERVERS.1.MESSAGE"))); + if (Config.getConfig().getBoolean("SELECTOR.SERVERS.1.BUNGEE.ENABLED")) { + BungeeChannel.sendToServer(player, Config.getConfig().getString("SELECTOR.SERVERS.1.BUNGEE.SERVER")); + } else { + if (Config.getConfig().getBoolean("SELECTOR.SERVERS.1.EZQUEUE.ENABLED")) { + EzQueueAPI.addToQueue(player, Config.getConfig().getString("SELECTOR.SERVERS.1.EZQUEUE.QUEUE")); + } else { + player.sendMessage(CC.translate("&cPlease activate the mode of travel to the mode.")); + } + } + event.setCancelled(true); + player.closeInventory(); + } + if (event.getCurrentItem().getType() == Material.valueOf(Config.getConfig().getString("SELECTOR.SERVERS.2.MATERIAL"))) { + player.sendMessage(CC.translate(Config.getConfig().getString("SELECTOR.SERVERS.2.MESSAGE"))); + event.setCancelled(true); + player.closeInventory(); + if (Config.getConfig().getBoolean("SELECTOR.SERVERS.2.BUNGEE.ENABLED")) { + BungeeChannel.sendToServer(player, Config.getConfig().getString("SELECTOR.SERVERS.2.BUNGEE.SERVER")); + } else { + if (Config.getConfig().getBoolean("SELECTOR.SERVERS.2.EZQUEUE.ENABLED")) { + EzQueueAPI.addToQueue(player, Config.getConfig().getString("SELECTOR.SERVERS.2.EZQUEUE.QUEUE")); + } else { + player.sendMessage(CC.translate("&cPlease activate the mode of travel to the mode.")); + } + } + } + if (event.getCurrentItem().getType() == Material.valueOf(Config.getConfig().getString("SELECTOR.SERVERS.3.MATERIAL"))) { + event.setCancelled(true); + player.closeInventory(); + player.sendMessage(CC.translate(Config.getConfig().getString("SELECTOR.SERVERS.3.MESSAGE"))); + if (Config.getConfig().getBoolean("SELECTOR.SERVERS.3.BUNGEE.ENABLED")) { + BungeeChannel.sendToServer(player, Config.getConfig().getString("SELECTOR.SERVERS.3.BUNGEE.SERVER")); + } else { + if (Config.getConfig().getBoolean("SELECTOR.SERVERS.3.EZQUEUE.ENABLED")) { + EzQueueAPI.addToQueue(player, Config.getConfig().getString("SELECTOR.SERVERS.3.EZQUEUE.QUEUE")); + } else { + player.sendMessage(CC.translate("&cPlease activate the mode of travel to the mode.")); + } + } + } + } +} diff --git a/src/main/java/dev/aapy/listeners/hotbar/particles/ParticleEffect.java b/src/main/java/dev/aapy/listeners/hotbar/particles/ParticleEffect.java new file mode 100644 index 0000000..86f5908 --- /dev/null +++ b/src/main/java/dev/aapy/listeners/hotbar/particles/ParticleEffect.java @@ -0,0 +1,661 @@ +package dev.aapy.listeners.hotbar.particles; + +import org.bukkit.entity.*; + +import java.util.*; +import java.lang.reflect.*; + +import org.bukkit.*; +import org.bukkit.util.Vector; + +public enum ParticleEffect +{ + EXPLOSION_NORMAL("explode", 0, -1, new ParticleProperty[] { ParticleProperty.DIRECTIONAL }), + EXPLOSION_LARGE("largeexplode", 1, -1, new ParticleProperty[0]), + EXPLOSION_HUGE("hugeexplosion", 2, -1, new ParticleProperty[0]), + FIREWORKS_SPARK("fireworksSpark", 3, -1, new ParticleProperty[] { ParticleProperty.DIRECTIONAL }), + WATER_BUBBLE("bubble", 4, -1, new ParticleProperty[] { ParticleProperty.DIRECTIONAL, ParticleProperty.REQUIRES_WATER }), + WATER_SPLASH("splash", 5, -1, new ParticleProperty[] { ParticleProperty.DIRECTIONAL }), + WATER_WAKE("wake", 6, 7, new ParticleProperty[] { ParticleProperty.DIRECTIONAL }), + SUSPENDED("suspended", 7, -1, new ParticleProperty[] { ParticleProperty.REQUIRES_WATER }), + SUSPENDED_DEPTH("depthSuspend", 8, -1, new ParticleProperty[] { ParticleProperty.DIRECTIONAL }), + CRIT("crit", 9, -1, new ParticleProperty[] { ParticleProperty.DIRECTIONAL }), + CRIT_MAGIC("magicCrit", 10, -1, new ParticleProperty[] { ParticleProperty.DIRECTIONAL }), + SMOKE_NORMAL("smoke", 11, -1, new ParticleProperty[] { ParticleProperty.DIRECTIONAL }), + SMOKE_LARGE("largesmoke", 12, -1, new ParticleProperty[] { ParticleProperty.DIRECTIONAL }), + SPELL("spell", 13, -1, new ParticleProperty[0]), + SPELL_INSTANT("instantSpell", 14, -1, new ParticleProperty[0]), + SPELL_MOB("mobSpell", 15, -1, new ParticleProperty[] { ParticleProperty.COLORABLE }), + SPELL_MOB_AMBIENT("mobSpellAmbient", 16, -1, new ParticleProperty[] { ParticleProperty.COLORABLE }), + SPELL_WITCH("witchMagic", 17, -1, new ParticleProperty[0]), + DRIP_WATER("dripWater", 18, -1, new ParticleProperty[0]), + DRIP_LAVA("dripLava", 19, -1, new ParticleProperty[0]), + VILLAGER_ANGRY("angryVillager", 20, -1, new ParticleProperty[0]), + VILLAGER_HAPPY("happyVillager", 21, -1, new ParticleProperty[] { ParticleProperty.DIRECTIONAL }), + TOWN_AURA("townaura", 22, -1, new ParticleProperty[] { ParticleProperty.DIRECTIONAL }), + NOTE("note", 23, -1, new ParticleProperty[] { ParticleProperty.COLORABLE }), + PORTAL("portal", 24, -1, new ParticleProperty[] { ParticleProperty.DIRECTIONAL }), + ENCHANTMENT_TABLE("enchantmenttable", 25, -1, new ParticleProperty[] { ParticleProperty.DIRECTIONAL }), + FLAME("flame", 26, -1, new ParticleProperty[] { ParticleProperty.DIRECTIONAL }), + LAVA("lava", 27, -1, new ParticleProperty[0]), + FOOTSTEP("footstep", 28, -1, new ParticleProperty[0]), + CLOUD("cloud", 29, -1, new ParticleProperty[] { ParticleProperty.DIRECTIONAL }), + REDSTONE("reddust", 30, -1, new ParticleProperty[] { ParticleProperty.COLORABLE }), + SNOWBALL("snowballpoof", 31, -1, new ParticleProperty[0]), + SNOW_SHOVEL("snowshovel", 32, -1, new ParticleProperty[] { ParticleProperty.DIRECTIONAL }), + SLIME("slime", 33, -1, new ParticleProperty[0]), + HEART("heart", 34, -1, new ParticleProperty[0]), + BARRIER("barrier", 35, 8, new ParticleProperty[0]), + ITEM_CRACK("iconcrack", 36, -1, new ParticleProperty[] { ParticleProperty.DIRECTIONAL, ParticleProperty.REQUIRES_DATA }), + BLOCK_CRACK("blockcrack", 37, -1, new ParticleProperty[] { ParticleProperty.REQUIRES_DATA }), + BLOCK_DUST("blockdust", 38, 7, new ParticleProperty[] { ParticleProperty.DIRECTIONAL, ParticleProperty.REQUIRES_DATA }), + WATER_DROP("droplet", 39, 8, new ParticleProperty[0]), + ITEM_TAKE("take", 40, 8, new ParticleProperty[0]), + MOB_APPEARANCE("mobappearance", 41, 8, new ParticleProperty[0]); + + private static Map NAME_MAP; + private static Map ID_MAP; + private String name; + private int id; + private int requiredVersion; + private List properties; + + private ParticleEffect(String name, int id, int requiredVersion, ParticleProperty[] properties) { + this.name = name; + this.id = id; + this.requiredVersion = requiredVersion; + this.properties = Arrays.asList(properties); + } + + public String getName() { + return this.name; + } + + public int getId() { + return this.id; + } + + public int getRequiredVersion() { + return this.requiredVersion; + } + + public boolean hasProperty(ParticleProperty property) { + return this.properties.contains(property); + } + + public boolean isSupported() { + return this.requiredVersion == -1 || ParticlePacket.getVersion() >= this.requiredVersion; + } + + public static ParticleEffect fromName(String name) { + for (Map.Entry entry : ParticleEffect.NAME_MAP.entrySet()) { + if (!entry.getKey().equalsIgnoreCase(name)) { + continue; + } + return entry.getValue(); + } + return null; + } + + public static ParticleEffect fromId(int id) { + for (Map.Entry entry : ParticleEffect.ID_MAP.entrySet()) { + if (entry.getKey() != id) { + continue; + } + return entry.getValue(); + } + return null; + } + + private static boolean isWater(Location location) { + Material material = location.getBlock().getType(); + return material == Material.WATER || material == Material.STATIONARY_WATER; + } + + private static boolean isLongDistance(Location location, List players) { + String world = location.getWorld().getName(); + for (Player player : players) { + Location playerLocation = player.getLocation(); + if (world.equals(playerLocation.getWorld().getName())) { + if (playerLocation.distanceSquared(location) < 65536.0) { + continue; + } + return true; + } + } + return false; + } + + private static boolean isDataCorrect(ParticleEffect effect, ParticleData data) { + return ((effect == ParticleEffect.BLOCK_CRACK || effect == ParticleEffect.BLOCK_DUST) && data instanceof BlockData) || (effect == ParticleEffect.ITEM_CRACK && data instanceof ItemData); + } + + private static boolean isColorCorrect(ParticleEffect effect, ParticleColor color) { + return ((effect == ParticleEffect.SPELL_MOB || effect == ParticleEffect.SPELL_MOB_AMBIENT || effect == ParticleEffect.REDSTONE) && color instanceof OrdinaryColor) || (effect == ParticleEffect.NOTE && color instanceof NoteColor); + } + + public void display(float offsetX, float offsetY, float offsetZ, float speed, int amount, Location center, double range) throws ParticleVersionException, ParticleDataException, IllegalArgumentException { + if (!this.isSupported()) { + throw new ParticleVersionException("This particle effect is not supported by your server version"); + } + if (this.hasProperty(ParticleProperty.REQUIRES_DATA)) { + throw new ParticleDataException("This particle effect requires additional data"); + } + if (this.hasProperty(ParticleProperty.REQUIRES_WATER) && !isWater(center)) { + throw new IllegalArgumentException("There is no water at the center location"); + } + new ParticlePacket(this, offsetX, offsetY, offsetZ, speed, amount, range > 256.0, null).sendTo(center, range); + } + + public void display(float offsetX, float offsetY, float offsetZ, float speed, int amount, Location center, List players) throws ParticleVersionException, ParticleDataException, IllegalArgumentException { + if (!this.isSupported()) { + throw new ParticleVersionException("This particle effect is not supported by your server version"); + } + if (this.hasProperty(ParticleProperty.REQUIRES_DATA)) { + throw new ParticleDataException("This particle effect requires additional data"); + } + if (this.hasProperty(ParticleProperty.REQUIRES_WATER) && !isWater(center)) { + throw new IllegalArgumentException("There is no water at the center location"); + } + new ParticlePacket(this, offsetX, offsetY, offsetZ, speed, amount, isLongDistance(center, players), null).sendTo(center, players); + } + + public void display(float offsetX, float offsetY, float offsetZ, float speed, int amount, Location center, Player... players) throws ParticleVersionException, ParticleDataException, IllegalArgumentException { + this.display(offsetX, offsetY, offsetZ, speed, amount, center, Arrays.asList(players)); + } + + public void display(Vector direction, float speed, Location center, double range) throws ParticleVersionException, ParticleDataException, IllegalArgumentException { + if (!this.isSupported()) { + throw new ParticleVersionException("This particle effect is not supported by your server version"); + } + if (this.hasProperty(ParticleProperty.REQUIRES_DATA)) { + throw new ParticleDataException("This particle effect requires additional data"); + } + if (!this.hasProperty(ParticleProperty.DIRECTIONAL)) { + throw new IllegalArgumentException("This particle effect is not directional"); + } + if (this.hasProperty(ParticleProperty.REQUIRES_WATER) && !isWater(center)) { + throw new IllegalArgumentException("There is no water at the center location"); + } + new ParticlePacket(this, direction, speed, range > 256.0, null).sendTo(center, range); + } + + public void display(Vector direction, float speed, Location center, List players) throws ParticleVersionException, ParticleDataException, IllegalArgumentException { + if (!this.isSupported()) { + throw new ParticleVersionException("This particle effect is not supported by your server version"); + } + if (this.hasProperty(ParticleProperty.REQUIRES_DATA)) { + throw new ParticleDataException("This particle effect requires additional data"); + } + if (!this.hasProperty(ParticleProperty.DIRECTIONAL)) { + throw new IllegalArgumentException("This particle effect is not directional"); + } + if (this.hasProperty(ParticleProperty.REQUIRES_WATER) && !isWater(center)) { + throw new IllegalArgumentException("There is no water at the center location"); + } + new ParticlePacket(this, direction, speed, isLongDistance(center, players), null).sendTo(center, players); + } + + public void display(Vector direction, float speed, Location center, Player... players) throws ParticleVersionException, ParticleDataException, IllegalArgumentException { + this.display(direction, speed, center, Arrays.asList(players)); + } + + public void display(ParticleColor color, Location center, double range) throws ParticleVersionException, ParticleColorException { + if (!this.isSupported()) { + throw new ParticleVersionException("This particle effect is not supported by your server version"); + } + if (!this.hasProperty(ParticleProperty.COLORABLE)) { + throw new ParticleColorException("This particle effect is not colorable"); + } + if (!isColorCorrect(this, color)) { + throw new ParticleColorException("The particle color type is incorrect"); + } + new ParticlePacket(this, color, range > 256.0).sendTo(center, range); + } + + public void display(ParticleColor color, Location center, List players) throws ParticleVersionException, ParticleColorException { + if (!this.isSupported()) { + throw new ParticleVersionException("This particle effect is not supported by your server version"); + } + if (!this.hasProperty(ParticleProperty.COLORABLE)) { + throw new ParticleColorException("This particle effect is not colorable"); + } + if (!isColorCorrect(this, color)) { + throw new ParticleColorException("The particle color type is incorrect"); + } + new ParticlePacket(this, color, isLongDistance(center, players)).sendTo(center, players); + } + + public void display(ParticleColor color, Location center, Player... players) throws ParticleVersionException, ParticleColorException { + this.display(color, center, Arrays.asList(players)); + } + + public void display(ParticleData data, float offsetX, float offsetY, float offsetZ, float speed, int amount, Location center, double range) throws ParticleVersionException, ParticleDataException { + if (!this.isSupported()) { + throw new ParticleVersionException("This particle effect is not supported by your server version"); + } + if (!this.hasProperty(ParticleProperty.REQUIRES_DATA)) { + throw new ParticleDataException("This particle effect does not require additional data"); + } + if (!isDataCorrect(this, data)) { + throw new ParticleDataException("The particle data type is incorrect"); + } + new ParticlePacket(this, offsetX, offsetY, offsetZ, speed, amount, range > 256.0, data).sendTo(center, range); + } + + public void display(ParticleData data, float offsetX, float offsetY, float offsetZ, float speed, int amount, Location center, List players) throws ParticleVersionException, ParticleDataException { + if (!this.isSupported()) { + throw new ParticleVersionException("This particle effect is not supported by your server version"); + } + if (!this.hasProperty(ParticleProperty.REQUIRES_DATA)) { + throw new ParticleDataException("This particle effect does not require additional data"); + } + if (!isDataCorrect(this, data)) { + throw new ParticleDataException("The particle data type is incorrect"); + } + new ParticlePacket(this, offsetX, offsetY, offsetZ, speed, amount, isLongDistance(center, players), data).sendTo(center, players); + } + + public void display(ParticleData data, float offsetX, float offsetY, float offsetZ, float speed, int amount, Location center, Player... players) throws ParticleVersionException, ParticleDataException { + this.display(data, offsetX, offsetY, offsetZ, speed, amount, center, Arrays.asList(players)); + } + + public void display(ParticleData data, Vector direction, float speed, Location center, double range) throws ParticleVersionException, ParticleDataException { + if (!this.isSupported()) { + throw new ParticleVersionException("This particle effect is not supported by your server version"); + } + if (!this.hasProperty(ParticleProperty.REQUIRES_DATA)) { + throw new ParticleDataException("This particle effect does not require additional data"); + } + if (!isDataCorrect(this, data)) { + throw new ParticleDataException("The particle data type is incorrect"); + } + new ParticlePacket(this, direction, speed, range > 256.0, data).sendTo(center, range); + } + + public void display(ParticleData data, Vector direction, float speed, Location center, List players) throws ParticleVersionException, ParticleDataException { + if (!this.isSupported()) { + throw new ParticleVersionException("This particle effect is not supported by your server version"); + } + if (!this.hasProperty(ParticleProperty.REQUIRES_DATA)) { + throw new ParticleDataException("This particle effect does not require additional data"); + } + if (!isDataCorrect(this, data)) { + throw new ParticleDataException("The particle data type is incorrect"); + } + new ParticlePacket(this, direction, speed, isLongDistance(center, players), data).sendTo(center, players); + } + + public void display(ParticleData data, Vector direction, float speed, Location center, Player... players) throws ParticleVersionException, ParticleDataException { + this.display(data, direction, speed, center, Arrays.asList(players)); + } + + static { + NAME_MAP = new HashMap(); + ID_MAP = new HashMap(); + for (ParticleEffect effect : values()) { + ParticleEffect.NAME_MAP.put(effect.name, effect); + ParticleEffect.ID_MAP.put(effect.id, effect); + } + } + + public enum ParticleProperty + { + REQUIRES_WATER, + REQUIRES_DATA, + DIRECTIONAL, + COLORABLE; + } + + public abstract static class ParticleData + { + private Material material; + private byte data; + private int[] packetData; + + public ParticleData(Material material, byte data) { + this.material = material; + this.data = data; + this.packetData = new int[] { material.getId(), data }; + } + + public Material getMaterial() { + return this.material; + } + + public byte getData() { + return this.data; + } + + public int[] getPacketData() { + return this.packetData; + } + + public String getPacketDataString() { + return "_" + this.packetData[0] + "_" + this.packetData[1]; + } + } + + public static class ItemData extends ParticleData + { + public ItemData(Material material, byte data) { + super(material, data); + } + } + + public static class BlockData extends ParticleData + { + public BlockData(Material material, byte data) throws IllegalArgumentException { + super(material, data); + if (!material.isBlock()) { + throw new IllegalArgumentException("The material is not a block"); + } + } + } + + public abstract static class ParticleColor + { + public abstract float getValueX(); + + public abstract float getValueY(); + + public abstract float getValueZ(); + } + + public static class OrdinaryColor extends ParticleColor + { + private int red; + private int green; + private int blue; + + public OrdinaryColor(int red, int green, int blue) throws IllegalArgumentException { + if (red < 0) { + throw new IllegalArgumentException("The red value is lower than 0"); + } + if (red > 255) { + throw new IllegalArgumentException("The red value is higher than 255"); + } + this.red = red; + if (green < 0) { + throw new IllegalArgumentException("The green value is lower than 0"); + } + if (green > 255) { + throw new IllegalArgumentException("The green value is higher than 255"); + } + this.green = green; + if (blue < 0) { + throw new IllegalArgumentException("The blue value is lower than 0"); + } + if (blue > 255) { + throw new IllegalArgumentException("The blue value is higher than 255"); + } + this.blue = blue; + } + + public OrdinaryColor(Color color) { + this(color.getRed(), color.getGreen(), color.getBlue()); + } + + public int getRed() { + return this.red; + } + + public int getGreen() { + return this.green; + } + + public int getBlue() { + return this.blue; + } + + @Override + public float getValueX() { + return this.red / 255.0f; + } + + @Override + public float getValueY() { + return this.green / 255.0f; + } + + @Override + public float getValueZ() { + return this.blue / 255.0f; + } + } + + public static class NoteColor extends ParticleColor + { + private int note; + + public NoteColor(int note) throws IllegalArgumentException { + if (note < 0) { + throw new IllegalArgumentException("The note value is lower than 0"); + } + if (note > 24) { + throw new IllegalArgumentException("The note value is higher than 24"); + } + this.note = note; + } + + @Override + public float getValueX() { + return this.note / 24.0f; + } + + @Override + public float getValueY() { + return 0.0f; + } + + @Override + public float getValueZ() { + return 0.0f; + } + } + + private static class ParticleDataException extends RuntimeException + { + private static long serialVersionUID = 3203085387160737484L; + + public ParticleDataException(String message) { + super(message); + } + } + + private static class ParticleColorException extends RuntimeException + { + private static long serialVersionUID = 3203085387160737484L; + + public ParticleColorException(String message) { + super(message); + } + } + + private static class ParticleVersionException extends RuntimeException + { + private static long serialVersionUID = 3203085387160737484L; + + public ParticleVersionException(String message) { + super(message); + } + } + + public static class ParticlePacket + { + private static int version; + private static Class enumParticle; + private static Constructor packetConstructor; + private static Method getHandle; + private static Field playerConnection; + private static Method sendPacket; + private static boolean initialized; + private ParticleEffect effect; + private float offsetX; + private float offsetY; + private float offsetZ; + private float speed; + private int amount; + private boolean longDistance; + private ParticleData data; + private Object packet; + + public ParticlePacket(ParticleEffect effect, float offsetX, float offsetY, float offsetZ, float speed, int amount, boolean longDistance, ParticleData data) throws IllegalArgumentException { + initialize(); + if (speed < 0.0f) { + throw new IllegalArgumentException("The speed is lower than 0"); + } + if (amount < 0) { + throw new IllegalArgumentException("The amount is lower than 0"); + } + this.effect = effect; + this.offsetX = offsetX; + this.offsetY = offsetY; + this.offsetZ = offsetZ; + this.speed = speed; + this.amount = amount; + this.longDistance = longDistance; + this.data = data; + } + + public ParticlePacket(ParticleEffect effect, Vector direction, float speed, boolean longDistance, ParticleData data) throws IllegalArgumentException { + this(effect, (float)direction.getX(), (float)direction.getY(), (float)direction.getZ(), speed, 0, longDistance, data); + } + + public ParticlePacket(ParticleEffect effect, ParticleColor color, boolean longDistance) { + this(effect, color.getValueX(), color.getValueY(), color.getValueZ(), 1.0f, 0, longDistance, null); + if (effect == ParticleEffect.REDSTONE && color instanceof OrdinaryColor && ((OrdinaryColor)color).getRed() == 0) { + this.offsetX = Float.MIN_NORMAL; + } + } + + public static void initialize() throws VersionIncompatibleException { + if (ParticlePacket.initialized) { + return; + } + try { + ParticlePacket.version = Integer.parseInt(Character.toString(ReflectionUtils.PackageType.getServerVersion().charAt(3))); + if (ParticlePacket.version > 7) { + ParticlePacket.enumParticle = ReflectionUtils.PackageType.MINECRAFT_SERVER.getClass("EnumParticle"); + } + Class packetClass = ReflectionUtils.PackageType.MINECRAFT_SERVER.getClass((ParticlePacket.version < 7) ? "Packet63WorldParticles" : "PacketPlayOutWorldParticles"); + ParticlePacket.packetConstructor = ReflectionUtils.getConstructor(packetClass, (Class[])new Class[0]); + ParticlePacket.getHandle = ReflectionUtils.getMethod("CraftPlayer", ReflectionUtils.PackageType.CRAFTBUKKIT_ENTITY, "getHandle", (Class[])new Class[0]); + ParticlePacket.playerConnection = ReflectionUtils.getField("EntityPlayer", ReflectionUtils.PackageType.MINECRAFT_SERVER, false, "playerConnection"); + ParticlePacket.sendPacket = ReflectionUtils.getMethod(ParticlePacket.playerConnection.getType(), "sendPacket", ReflectionUtils.PackageType.MINECRAFT_SERVER.getClass("Packet")); + } + catch (Exception exception) { + throw new VersionIncompatibleException("Your current bukkit version seems to be incompatible with this library", exception); + } + ParticlePacket.initialized = true; + } + + public static int getVersion() { + if (!ParticlePacket.initialized) { + initialize(); + } + return ParticlePacket.version; + } + + public static boolean isInitialized() { + return ParticlePacket.initialized; + } + + private void initializePacket(Location center) throws PacketInstantiationException { + if (this.packet != null) { + return; + } + try { + this.packet = ParticlePacket.packetConstructor.newInstance(new Object[0]); + if (ParticlePacket.version < 8) { + String name = this.effect.getName(); + if (this.data != null) { + name += this.data.getPacketDataString(); + } + ReflectionUtils.setValue(this.packet, true, "a", name); + } + else { + ReflectionUtils.setValue(this.packet, true, "a", ParticlePacket.enumParticle.getEnumConstants()[this.effect.getId()]); + ReflectionUtils.setValue(this.packet, true, "j", this.longDistance); + if (this.data != null) { + int[] packetData = this.data.getPacketData(); + ReflectionUtils.setValue(this.packet, true, "k", (this.effect == ParticleEffect.ITEM_CRACK) ? packetData : new int[] { packetData[0] | packetData[1] << 12 }); + } + } + ReflectionUtils.setValue(this.packet, true, "b", (float)center.getX()); + ReflectionUtils.setValue(this.packet, true, "c", (float)center.getY()); + ReflectionUtils.setValue(this.packet, true, "d", (float)center.getZ()); + ReflectionUtils.setValue(this.packet, true, "e", this.offsetX); + ReflectionUtils.setValue(this.packet, true, "f", this.offsetY); + ReflectionUtils.setValue(this.packet, true, "g", this.offsetZ); + ReflectionUtils.setValue(this.packet, true, "h", this.speed); + ReflectionUtils.setValue(this.packet, true, "i", this.amount); + } + catch (Exception exception) { + throw new PacketInstantiationException("Packet instantiation failed", exception); + } + } + + public void sendTo(Location center, Player player) throws PacketInstantiationException, PacketSendingException { + this.initializePacket(center); + try { + ParticlePacket.sendPacket.invoke(ParticlePacket.playerConnection.get(ParticlePacket.getHandle.invoke(player, new Object[0])), this.packet); + } + catch (Exception exception) { + throw new PacketSendingException("Failed to send the packet to player '" + player.getName() + "'", exception); + } + } + + public void sendTo(Location center, List players) throws IllegalArgumentException { + if (players.isEmpty()) { + throw new IllegalArgumentException("The player list is empty"); + } + for (Player player : players) { + this.sendTo(center, player); + } + } + + public void sendTo(Location center, double range) throws IllegalArgumentException { + if (range < 1.0) { + throw new IllegalArgumentException("The range is lower than 1"); + } + String worldName = center.getWorld().getName(); + double squared = range * range; + for (Player player : Bukkit.getOnlinePlayers()) { + if (player.getWorld().getName().equals(worldName)) { + if (player.getLocation().distanceSquared(center) > squared) { + continue; + } + this.sendTo(center, player); + } + } + } + + private static class VersionIncompatibleException extends RuntimeException + { + private static long serialVersionUID = 3203085387160737484L; + + public VersionIncompatibleException(String message, Throwable cause) { + super(message, cause); + } + } + + private static class PacketInstantiationException extends RuntimeException + { + private static long serialVersionUID = 3203085387160737484L; + + public PacketInstantiationException(String message, Throwable cause) { + super(message, cause); + } + } + + private static class PacketSendingException extends RuntimeException + { + private static long serialVersionUID = 3203085387160737484L; + + public PacketSendingException(String message, Throwable cause) { + super(message, cause); + } + } + } +} diff --git a/src/main/java/dev/aapy/listeners/hotbar/particles/ParticleParameter.java b/src/main/java/dev/aapy/listeners/hotbar/particles/ParticleParameter.java new file mode 100644 index 0000000..e39fecf --- /dev/null +++ b/src/main/java/dev/aapy/listeners/hotbar/particles/ParticleParameter.java @@ -0,0 +1,15 @@ +package dev.aapy.listeners.hotbar.particles; + +import org.bukkit.entity.Player; + +import java.util.HashMap; +import java.util.Map; + +public class ParticleParameter { + + public static Map set; + + static{ + ParticleParameter.set =new HashMap(); + } +} diff --git a/src/main/java/dev/aapy/listeners/hotbar/particles/Particles.java b/src/main/java/dev/aapy/listeners/hotbar/particles/Particles.java new file mode 100644 index 0000000..0daec0b --- /dev/null +++ b/src/main/java/dev/aapy/listeners/hotbar/particles/Particles.java @@ -0,0 +1,109 @@ +package dev.aapy.listeners.hotbar.particles; + +import dev.aapy.SnakeHub; +import dev.aapy.file.Config; +import dev.aapy.util.ArmorCreator; +import dev.aapy.util.CC; +import dev.aapy.util.ItemCreator; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.plugin.Plugin; + +import java.util.Arrays; +import java.util.List; + +public class Particles implements Listener { + + public static void ParticleInv(Player p) { + Inventory inv = Bukkit.createInventory(null, 9 * 4, CC.translate("&cParticle Menu")); + List clearparticles = Arrays.asList("","&6Click to clear particle",""); + + inv.setItem(12 - 1, new ItemCreator(Material.BLAZE_POWDER).title("&6Flame Particle").build()); + inv.setItem(14 - 1, new ItemCreator(Material.TNT).title("&eExplosion Particle").build()); + inv.setItem(16 - 1, new ItemCreator(Material.REDSTONE).title("&cHeart Particle").build()); + inv.setItem(18 - 1, new ItemCreator(Material.WATER_BUCKET).title("&dWater Particle").build()); + + if (Config.getConfig().getBoolean("COSMETIC.GLASS_PANEL.ENABLED")) { + ItemStack panel = new ArmorCreator(Material.STAINED_GLASS_PANE, 1, (short) Config.getConfig().getInt("COSMETIC.GLASS_PANEL.ID")).setName("").build(); + + for (int i = 0; i < inv.getSize(); i++) { + if (inv.getItem(i) == null) { + inv.setItem(i, panel); + } + } + } + + p.openInventory(inv); + } + + @EventHandler + public void onClickInventory (InventoryClickEvent event) { + Player player = (Player) event.getWhoClicked(); + ItemStack item = event.getCurrentItem(); + if (event.getCurrentItem() == null || event.getCurrentItem().getType() == Material.AIR || !event.getCurrentItem().hasItemMeta()) { + return; + } + if (event.getCurrentItem().getItemMeta() == null) { + return; + } + if (event.getClickedInventory().getTitle().equalsIgnoreCase(CC.translate("&cParticle Menu"))) { + if (player.hasPermission("hub.admin") && player.hasPermission("hub.donator")) { + if (event.getSlot() == 12 - 1) { + if(ParticleParameter.set.containsKey(player)){ + Bukkit.getScheduler().cancelTask((int)ParticleParameter.set.get(player)); + ParticleParameter.set.replace(player, Bukkit.getServer().getScheduler().scheduleSyncRepeatingTask((Plugin) SnakeHub.getInst(), () -> ParticleEffect.FLAME.display(10.0f, 15.0f, 0.0f, 0.0f, 0, player.getLocation().add(-0.0, 2.0, 0.0), 10.0), 0L, 0L)); + player.sendMessage(CC.translate("&fYou has been Changed your &cParticle!")); + player.closeInventory(); + }else { + ParticleParameter.set.put(player, Bukkit.getServer().getScheduler().scheduleSyncRepeatingTask((Plugin) SnakeHub.getInst(), () -> ParticleEffect.FLAME.display(10.0f, 15.0f, 0.0f, 0.0f, 0, player.getLocation().add(-0.0, 2.0, 0.0), 10.0), 0L, 0L)); + player.sendMessage(CC.translate("&fYou has been set &6Flame &fParticle!")); + player.closeInventory(); + } + }else if(event.getSlot() == 14 - 1){ + if(ParticleParameter.set.containsKey(player)){ + Bukkit.getScheduler().cancelTask((int)ParticleParameter.set.get(player)); + ParticleParameter.set.replace(player, Bukkit.getServer().getScheduler().scheduleSyncRepeatingTask((Plugin) SnakeHub.getInst(), () -> ParticleEffect.EXPLOSION_NORMAL.display(10.0f, 15.0f, 0.0f, 0.0f, 0, player.getLocation().add(-0.0, 2.0, 0.0), 10.0), 0L, 0L)); + player.sendMessage(CC.translate("&fYou has been Changed your &cParticle!")); + player.closeInventory(); + }else { + ParticleParameter.set.put(player, Bukkit.getServer().getScheduler().scheduleSyncRepeatingTask((Plugin) SnakeHub.getInst(), () -> ParticleEffect.EXPLOSION_NORMAL.display(10.0f, 15.0f, 0.0f, 0.0f, 0, player.getLocation().add(-0.0, 2.0, 0.0), 10.0), 0L, 0L)); + player.sendMessage(CC.translate("&fYou has been set &eExplosion &fParticle!")); + player.closeInventory(); + } + }else if(event.getSlot() == 16 - 1){ + if(ParticleParameter.set.containsKey(player)){ + Bukkit.getScheduler().cancelTask((int)ParticleParameter.set.get(player)); + ParticleParameter.set.replace(player, Bukkit.getServer().getScheduler().scheduleSyncRepeatingTask((Plugin) SnakeHub.getInst(), () -> ParticleEffect.HEART.display(10.0f, 15.0f, 0.0f, 0.0f, 0, player.getLocation().add(-0.0, 2.0, 0.0), 10.0), 0L, 0L)); + player.sendMessage(CC.translate("&fYou has been Changed your &cParticle!")); + player.closeInventory(); + }else { + ParticleParameter.set.put(player, Bukkit.getServer().getScheduler().scheduleSyncRepeatingTask((Plugin) SnakeHub.getInst(), () -> ParticleEffect.HEART.display(10.0f, 15.0f, 0.0f, 0.0f, 0, player.getLocation().add(-0.0, 2.0, 0.0), 10.0), 0L, 0L)); + player.sendMessage(CC.translate("&fYou has been set &cHeart &fParticle!")); + player.closeInventory(); + } + }else if(event.getSlot() == 18 - 1) { + if (ParticleParameter.set.containsKey(player)) { + Bukkit.getScheduler().cancelTask((int) ParticleParameter.set.get(player)); + ParticleParameter.set.replace(player, Bukkit.getServer().getScheduler().scheduleSyncRepeatingTask((Plugin) SnakeHub.getInst(), () -> ParticleEffect.DRIP_WATER.display(10.0f, 15.0f, 0.0f, 0.0f, 0, player.getLocation().add(-0.0, 2.0, 0.0), 10.0), 0L, 0L)); + player.sendMessage(CC.translate("&fYou has been Changed your &cParticle!")); + player.closeInventory(); + } else { + ParticleParameter.set.put(player, Bukkit.getServer().getScheduler().scheduleSyncRepeatingTask((Plugin) SnakeHub.getInst(), () -> ParticleEffect.DRIP_WATER.display(10.0f, 15.0f, 0.0f, 0.0f, 0, player.getLocation().add(-0.0, 2.0, 0.0), 10.0), 0L, 0L)); + player.sendMessage(CC.translate("&fYou has been set &cWater &fParticle!")); + player.closeInventory(); + } + } + } else { + player.sendMessage(CC.translate(Config.getConfig().getString("SOCIAL.STORE"))); + player.closeInventory(); + event.setCancelled(true); + } + } + } +} diff --git a/src/main/java/dev/aapy/listeners/hotbar/particles/ReflectionUtils.java b/src/main/java/dev/aapy/listeners/hotbar/particles/ReflectionUtils.java new file mode 100644 index 0000000..a72c3a4 --- /dev/null +++ b/src/main/java/dev/aapy/listeners/hotbar/particles/ReflectionUtils.java @@ -0,0 +1,246 @@ +package dev.aapy.listeners.hotbar.particles; + + +import java.lang.reflect.*; +import org.bukkit.*; +import java.util.*; + +public final class ReflectionUtils +{ + private ReflectionUtils() { + } + + public static Constructor getConstructor(final Class clazz, final Class... parameterTypes) throws NoSuchMethodException { + final Class[] primitiveTypes = DataType.getPrimitive(parameterTypes); + for (final Constructor constructor : clazz.getConstructors()) { + if (DataType.compare(DataType.getPrimitive(constructor.getParameterTypes()), primitiveTypes)) { + return constructor; + } + } + throw new NoSuchMethodException("There is no such constructor in this class with the specified parameter types"); + } + + public static Constructor getConstructor(final String className, final PackageType packageType, final Class... parameterTypes) throws NoSuchMethodException, ClassNotFoundException { + return getConstructor(packageType.getClass(className), parameterTypes); + } + + public static Object instantiateObject(final Class clazz, final Object... arguments) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException { + return getConstructor(clazz, DataType.getPrimitive(arguments)).newInstance(arguments); + } + + public static Object instantiateObject(final String className, final PackageType packageType, final Object... arguments) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, ClassNotFoundException { + return instantiateObject(packageType.getClass(className), arguments); + } + + public static Method getMethod(final Class clazz, final String methodName, final Class... parameterTypes) throws NoSuchMethodException { + final Class[] primitiveTypes = DataType.getPrimitive(parameterTypes); + for (final Method method : clazz.getMethods()) { + if (method.getName().equals(methodName) && DataType.compare(DataType.getPrimitive(method.getParameterTypes()), primitiveTypes)) { + return method; + } + } + throw new NoSuchMethodException("There is no such method in this class with the specified name and parameter types"); + } + + public static Method getMethod(final String className, final PackageType packageType, final String methodName, final Class... parameterTypes) throws NoSuchMethodException, ClassNotFoundException { + return getMethod(packageType.getClass(className), methodName, parameterTypes); + } + + public static Object invokeMethod(final Object instance, final String methodName, final Object... arguments) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException { + return getMethod(instance.getClass(), methodName, DataType.getPrimitive(arguments)).invoke(instance, arguments); + } + + public static Object invokeMethod(final Object instance, final Class clazz, final String methodName, final Object... arguments) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException { + return getMethod(clazz, methodName, DataType.getPrimitive(arguments)).invoke(instance, arguments); + } + + public static Object invokeMethod(final Object instance, final String className, final PackageType packageType, final String methodName, final Object... arguments) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, ClassNotFoundException { + return invokeMethod(instance, packageType.getClass(className), methodName, arguments); + } + + public static Field getField(final Class clazz, final boolean declared, final String fieldName) throws NoSuchFieldException, SecurityException { + final Field field = declared ? clazz.getDeclaredField(fieldName) : clazz.getField(fieldName); + field.setAccessible(true); + return field; + } + + public static Field getField(final String className, final PackageType packageType, final boolean declared, final String fieldName) throws NoSuchFieldException, SecurityException, ClassNotFoundException { + return getField(packageType.getClass(className), declared, fieldName); + } + + public static Object getValue(final Object instance, final Class clazz, final boolean declared, final String fieldName) throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException { + return getField(clazz, declared, fieldName).get(instance); + } + + public static Object getValue(final Object instance, final String className, final PackageType packageType, final boolean declared, final String fieldName) throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException, ClassNotFoundException { + return getValue(instance, packageType.getClass(className), declared, fieldName); + } + + public static Object getValue(final Object instance, final boolean declared, final String fieldName) throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException { + return getValue(instance, instance.getClass(), declared, fieldName); + } + + public static void setValue(final Object instance, final Class clazz, final boolean declared, final String fieldName, final Object value) throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException { + getField(clazz, declared, fieldName).set(instance, value); + } + + public static void setValue(final Object instance, final String className, final PackageType packageType, final boolean declared, final String fieldName, final Object value) throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException, ClassNotFoundException { + setValue(instance, packageType.getClass(className), declared, fieldName, value); + } + + public static void setValue(final Object instance, final boolean declared, final String fieldName, final Object value) throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException { + setValue(instance, instance.getClass(), declared, fieldName, value); + } + + public enum PackageType + { + MINECRAFT_SERVER("net.minecraft.server." + getServerVersion()), + CRAFTBUKKIT("org.bukkit.craftbukkit." + getServerVersion()), + CRAFTBUKKIT_BLOCK(PackageType.CRAFTBUKKIT, "block"), + CRAFTBUKKIT_CHUNKIO(PackageType.CRAFTBUKKIT, "chunkio"), + CRAFTBUKKIT_COMMAND(PackageType.CRAFTBUKKIT, "command"), + CRAFTBUKKIT_CONVERSATIONS(PackageType.CRAFTBUKKIT, "conversations"), + CRAFTBUKKIT_ENCHANTMENS(PackageType.CRAFTBUKKIT, "enchantments"), + CRAFTBUKKIT_ENTITY(PackageType.CRAFTBUKKIT, "entity"), + CRAFTBUKKIT_EVENT(PackageType.CRAFTBUKKIT, "event"), + CRAFTBUKKIT_GENERATOR(PackageType.CRAFTBUKKIT, "generator"), + CRAFTBUKKIT_HELP(PackageType.CRAFTBUKKIT, "help"), + CRAFTBUKKIT_INVENTORY(PackageType.CRAFTBUKKIT, "inventory"), + CRAFTBUKKIT_MAP(PackageType.CRAFTBUKKIT, "map"), + CRAFTBUKKIT_METADATA(PackageType.CRAFTBUKKIT, "metadata"), + CRAFTBUKKIT_POTION(PackageType.CRAFTBUKKIT, "potion"), + CRAFTBUKKIT_PROJECTILES(PackageType.CRAFTBUKKIT, "projectiles"), + CRAFTBUKKIT_SCHEDULER(PackageType.CRAFTBUKKIT, "scheduler"), + CRAFTBUKKIT_SCOREBOARD(PackageType.CRAFTBUKKIT, "scoreboard"), + CRAFTBUKKIT_UPDATER(PackageType.CRAFTBUKKIT, "updater"), + CRAFTBUKKIT_UTIL(PackageType.CRAFTBUKKIT, "util"); + + private final String path; + + private PackageType(final String path) { + this.path = path; + } + + private PackageType(final PackageType parent, final String path) { + this(parent + "." + path); + } + + public String getPath() { + return this.path; + } + + public Class getClass(final String className) throws ClassNotFoundException { + return Class.forName(this + "." + className); + } + + @Override + public String toString() { + return this.path; + } + + public static String getServerVersion() { + return Bukkit.getServer().getClass().getPackage().getName().substring(23); + } + } + + public enum DataType + { + BYTE((Class)Byte.TYPE, (Class)Byte.class), + SHORT((Class)Short.TYPE, (Class)Short.class), + INTEGER((Class)Integer.TYPE, (Class)Integer.class), + LONG((Class)Long.TYPE, (Class)Long.class), + CHARACTER((Class)Character.TYPE, (Class)Character.class), + FLOAT((Class)Float.TYPE, (Class)Float.class), + DOUBLE((Class)Double.TYPE, (Class)Double.class), + BOOLEAN((Class)Boolean.TYPE, (Class)Boolean.class); + + private static final Map, DataType> CLASS_MAP; + private final Class primitive; + private final Class reference; + + private DataType(final Class primitive, final Class reference) { + this.primitive = primitive; + this.reference = reference; + } + + public Class getPrimitive() { + return this.primitive; + } + + public Class getReference() { + return this.reference; + } + + public static DataType fromClass(final Class clazz) { + return DataType.CLASS_MAP.get(clazz); + } + + public static Class getPrimitive(final Class clazz) { + final DataType type = fromClass(clazz); + return (type == null) ? clazz : type.getPrimitive(); + } + + public static Class getReference(final Class clazz) { + final DataType type = fromClass(clazz); + return (type == null) ? clazz : type.getReference(); + } + + public static Class[] getPrimitive(final Class[] classes) { + final int length = (classes == null) ? 0 : classes.length; + final Class[] types = (Class[])new Class[length]; + for (int index = 0; index < length; ++index) { + types[index] = getPrimitive(classes[index]); + } + return types; + } + + public static Class[] getReference(final Class[] classes) { + final int length = (classes == null) ? 0 : classes.length; + final Class[] types = (Class[])new Class[length]; + for (int index = 0; index < length; ++index) { + types[index] = getReference(classes[index]); + } + return types; + } + + public static Class[] getPrimitive(final Object[] objects) { + final int length = (objects == null) ? 0 : objects.length; + final Class[] types = (Class[])new Class[length]; + for (int index = 0; index < length; ++index) { + types[index] = getPrimitive(objects[index].getClass()); + } + return types; + } + + public static Class[] getReference(final Object[] objects) { + final int length = (objects == null) ? 0 : objects.length; + final Class[] types = (Class[])new Class[length]; + for (int index = 0; index < length; ++index) { + types[index] = getReference(objects[index].getClass()); + } + return types; + } + + public static boolean compare(final Class[] primary, final Class[] secondary) { + if (primary == null || secondary == null || primary.length != secondary.length) { + return false; + } + for (int index = 0; index < primary.length; ++index) { + final Class primaryClass = primary[index]; + final Class secondaryClass = secondary[index]; + if (!primaryClass.equals(secondaryClass) && !primaryClass.isAssignableFrom(secondaryClass)) { + return false; + } + } + return true; + } + + static { + CLASS_MAP = new HashMap, DataType>(); + for (final DataType type : values()) { + DataType.CLASS_MAP.put(type.primitive, type); + DataType.CLASS_MAP.put(type.reference, type); + } + } + } +} diff --git a/src/main/java/dev/aapy/manager/Manager.java b/src/main/java/dev/aapy/manager/Manager.java new file mode 100644 index 0000000..e4e1d75 --- /dev/null +++ b/src/main/java/dev/aapy/manager/Manager.java @@ -0,0 +1,43 @@ +package dev.aapy.manager; + +import com.google.common.collect.Lists; +import dev.aapy.SnakeHub; +import dev.aapy.manager.handler.Handler; +import dev.aapy.manager.managers.*; +import lombok.Getter; + +import java.util.Arrays; +import java.util.List; + +/** + * @author 7qv_ and Alexito2060 on 19/2/2022. + * @project SnakeHub + */ + +@Getter +public class Manager { + + private final SnakeHub plugin; + private final List managers = Lists.newArrayList(); + + private ScoreBoardManager scoreboard; + private CommandManager command; + private ListenerManager listener; + + public Manager(SnakeHub plugin) { + this.plugin = plugin; + } + + public void enable() { + this.scoreboard = new ScoreBoardManager(this.plugin); + this.command = new CommandManager(this.plugin); + this.listener = new ListenerManager(this.plugin); + this.managers.addAll(Arrays.asList(this.scoreboard, this.command, this.listener)); + this.managers.forEach(Handler::enable); + } + + public void disable() { + this.managers.forEach(Handler::disable); + } + +} diff --git a/src/main/java/dev/aapy/manager/handler/Handler.java b/src/main/java/dev/aapy/manager/handler/Handler.java new file mode 100644 index 0000000..df8bd38 --- /dev/null +++ b/src/main/java/dev/aapy/manager/handler/Handler.java @@ -0,0 +1,22 @@ +package dev.aapy.manager.handler; + +import dev.aapy.SnakeHub; + +/** + * @author 7qv_ and Alexti2o600 on 19/2/2022. + * @project Snake + Hub + */ + +public abstract class Handler { + + private final SnakeHub plugin; + + public Handler(SnakeHub plugin) { this.plugin = plugin; } + + public void enable() { } + + public void disable() { } + + public SnakeHub getPlugin() { return plugin; } +} diff --git a/src/main/java/dev/aapy/manager/managers/CommandManager.java b/src/main/java/dev/aapy/manager/managers/CommandManager.java new file mode 100644 index 0000000..0c56c87 --- /dev/null +++ b/src/main/java/dev/aapy/manager/managers/CommandManager.java @@ -0,0 +1,37 @@ +package dev.aapy.manager.managers; + +import dev.alex.net.utilities.command.Command; +import dev.aapy.SnakeHub; +import dev.aapy.commands.plugin.HubCore; +import dev.aapy.commands.social.*; +import dev.aapy.manager.handler.Handler; + +/** + * @author 7qv_ and Alexito2060 on 19/2/2022. + * @project SnakeHub + * +**/ + +public final class CommandManager extends Handler { + + private Command command; + + public CommandManager(SnakeHub plugin) { super(plugin); } + + @Override + public void enable() { + this.command = new Command("", false); + command.register(new HubCore()); + command.register(new WebSite()); + command.register(new Twitter()); + command.register(new TeamSpeak()); + command.register(new Store()); + command.register(new Discord()); + this.command.registerAll(); + } + + @Override + public void disable() { + this.command.unregisterAll(); + } +} \ No newline at end of file diff --git a/src/main/java/dev/aapy/manager/managers/ListenerManager.java b/src/main/java/dev/aapy/manager/managers/ListenerManager.java new file mode 100644 index 0000000..c6f1fb8 --- /dev/null +++ b/src/main/java/dev/aapy/manager/managers/ListenerManager.java @@ -0,0 +1,49 @@ +package dev.aapy.manager.managers; + +import com.google.common.collect.Lists; +import dev.aapy.SnakeHub; +import dev.aapy.file.Config; +import dev.aapy.listeners.*; +import dev.aapy.listeners.hotbar.*; +import dev.aapy.listeners.hotbar.particles.Particles; +import dev.aapy.manager.handler.Handler; +import lombok.Getter; +import org.bukkit.plugin.PluginManager; + +import java.util.List; + +/** + * @author 7qv_ and Alexito2060 on 19/2/2022. + * @project SnakeHub + */ + +@Getter +public final class ListenerManager extends Handler { + + private final List listener = Lists.newArrayList(); + + public ListenerManager(SnakeHub plugin) { super(plugin); } + + @Override + public void enable() { + PluginManager manager = getPlugin().getServer().getPluginManager(); + manager.registerEvents(new PlayerListener(),getPlugin()); + if (Config.getConfig().getBoolean("BOOLEANS.LUNAR-CLIENT.NAMETAG")) { + manager.registerEvents(new LunarListener(), getPlugin()); + } + manager.registerEvents(new DeveloperListener(), getPlugin()); + manager.registerEvents(new EnderButtListener(), getPlugin()); + manager.registerEvents(new ChatFormatListener(), getPlugin()); + manager.registerEvents(new JumpListener(), getPlugin()); + manager.registerEvents(new LaunchPadListener(), getPlugin()); + manager.registerEvents(new Particles(), getPlugin()); + manager.registerEvents(new PlayerInvisibilityListener(), getPlugin()); + manager.registerEvents(new PvPListener(), getPlugin()); + manager.registerEvents(new OutfitsListener(), getPlugin()); + manager.registerEvents(new CosmeticListener(), getPlugin()); + manager.registerEvents(new SelectorListener(), getPlugin()); + manager.registerEvents(new CosmeticListener(), getPlugin()); + manager.registerEvents(new ChatFormatListener(), getPlugin()); + manager.registerEvents(new WorldListener(), getPlugin()); + } +} diff --git a/src/main/java/dev/aapy/manager/managers/PermissionManager.java b/src/main/java/dev/aapy/manager/managers/PermissionManager.java new file mode 100644 index 0000000..dbd4955 --- /dev/null +++ b/src/main/java/dev/aapy/manager/managers/PermissionManager.java @@ -0,0 +1,41 @@ +package dev.aapy.manager.managers; + +import dev.aapy.SnakeHub; +import dev.aapy.ranks.Permission; +import dev.aapy.ranks.type.AquaCore; +import dev.aapy.ranks.type.Default; +import dev.aapy.ranks.type.LuckPerms; +import lombok.Getter; +import org.bukkit.Bukkit; +import org.bukkit.plugin.RegisteredServiceProvider; + +import net.milkbowl.vault.chat.Chat; + +@Getter +public final class PermissionManager { + + private final SnakeHub plugin; + private String name; + private Permission permission; + private net.luckperms.api.LuckPerms luckperms; + private Chat chat; + + public PermissionManager(SnakeHub plugin) { this.plugin = plugin; } + + public void loadHook() { + if (Bukkit.getPluginManager().getPlugin("AquaCore") != null) this.setPermission(new AquaCore(), "AquaCore"); + if (Bukkit.getPluginManager().getPlugin("Vault") != null && this.loadVault() && this.getChat().getName().contains("LuckPerms")) this.setPermission(new LuckPerms(), "LuckPerms"); + this.setPermission(new Default(), "None"); + } + + private boolean loadVault() { + RegisteredServiceProvider service = this.plugin.getServer().getServicesManager().getRegistration(Chat.class); + if (service != null) this.chat = service.getProvider(); + return this.chat != null; + } + + private void setPermission(Permission permission, String name) { + this.permission = permission; + this.name = name; + } +} \ No newline at end of file diff --git a/src/main/java/dev/aapy/manager/managers/ScoreBoardManager.java b/src/main/java/dev/aapy/manager/managers/ScoreBoardManager.java new file mode 100644 index 0000000..eeb7479 --- /dev/null +++ b/src/main/java/dev/aapy/manager/managers/ScoreBoardManager.java @@ -0,0 +1,41 @@ +package dev.aapy.manager.managers; + +import dev.aapy.SnakeHub; +import dev.aapy.file.Config; +import dev.aapy.manager.handler.Handler; +import dev.aapy.scoreboard.ScoreBoardProvider; +import dev.aapy.scoreboard.assamble.Assemble; +import dev.aapy.scoreboard.assamble.AssembleStyle; +import dev.aapy.util.ScoreFooterTask; +import dev.aapy.util.ScoreTitleTask; +import lombok.Getter; + +/** + * @author 7qv_ on 20/2/2022. + * @project SnakeHub + */ + +@Getter +public final class ScoreBoardManager extends Handler { + + private ScoreFooterTask scoreTask; + private ScoreTitleTask scoreTitleTask; + + public ScoreBoardManager(SnakeHub plugin) { + super(plugin); + } + + @Override + public void enable() { + Assemble assemble = new Assemble(this.getPlugin(), new ScoreBoardProvider()); + assemble.setTicks(2); + assemble.setAssembleStyle(AssembleStyle.VIPER); + + if (Config.getConfig().getBoolean("BOOLEANS.SCOREBOARD.ANIMATED.FOOTER")) { + (this.scoreTask = new ScoreFooterTask()).runTaskTimerAsynchronously(this.getPlugin(), 0L, 20L); + } + if (Config.getConfig().getBoolean("BOOLEANS.SCOREBOARD.ANIMATED.TITLE")) { + (this.scoreTitleTask = new ScoreTitleTask()).runTaskTimerAsynchronously(this.getPlugin(), 0L, 20L); + } + } +} diff --git a/src/main/java/dev/aapy/ranks/Permission.java b/src/main/java/dev/aapy/ranks/Permission.java new file mode 100644 index 0000000..3fa0045 --- /dev/null +++ b/src/main/java/dev/aapy/ranks/Permission.java @@ -0,0 +1,14 @@ +package dev.aapy.ranks; + +import org.bukkit.OfflinePlayer; + +public interface Permission { + + String getName(OfflinePlayer offlinePlayer); + + String getPrefix(OfflinePlayer offlinePlayer); + + String getSuffix(OfflinePlayer offlinePlayer); + + String getColor(OfflinePlayer offlinePlayer); +} diff --git a/src/main/java/dev/aapy/ranks/type/AquaCore.java b/src/main/java/dev/aapy/ranks/type/AquaCore.java new file mode 100644 index 0000000..0c841fa --- /dev/null +++ b/src/main/java/dev/aapy/ranks/type/AquaCore.java @@ -0,0 +1,34 @@ +package dev.aapy.ranks.type; + +import dev.aapy.ranks.Permission; +import org.bukkit.OfflinePlayer; + +import me.activated.core.api.player.PlayerData; +import me.activated.core.plugin.AquaCoreAPI; + +public class AquaCore implements Permission { + + @Override + public String getName(OfflinePlayer player) { + PlayerData data = AquaCoreAPI.INSTANCE.getPlayerData(player.getUniqueId()); + return (data == null) ? "None" : data.getHighestRank().getName(); + } + + @Override + public String getPrefix(OfflinePlayer player) { + PlayerData data = AquaCoreAPI.INSTANCE.getPlayerData(player.getUniqueId()); + return (data == null) ? "None" : data.getHighestRank().getPrefix(); + } + + @Override + public String getSuffix(OfflinePlayer player) { + PlayerData data = AquaCoreAPI.INSTANCE.getPlayerData(player.getUniqueId()); + return (data == null) ? "None" : data.getHighestRank().getSuffix(); + } + + @Override + public String getColor(OfflinePlayer player) { + PlayerData data = AquaCoreAPI.INSTANCE.getPlayerData(player.getUniqueId()); + return (data == null) ? "None" : data.getHighestRank().getColor() + data.getHighestRank().getName(); + } +} diff --git a/src/main/java/dev/aapy/ranks/type/Default.java b/src/main/java/dev/aapy/ranks/type/Default.java new file mode 100644 index 0000000..107f184 --- /dev/null +++ b/src/main/java/dev/aapy/ranks/type/Default.java @@ -0,0 +1,28 @@ +package dev.aapy.ranks.type; + +import dev.aapy.ranks.Permission; +import org.bukkit.OfflinePlayer; + + +public class Default implements Permission { + + @Override + public String getName(OfflinePlayer player) { + return "None"; + } + + @Override + public String getPrefix(OfflinePlayer player) { + return "None"; + } + + @Override + public String getSuffix(OfflinePlayer player) { + return "None"; + } + + @Override + public String getColor(OfflinePlayer player) { + return "None"; + } +} diff --git a/src/main/java/dev/aapy/ranks/type/LuckPerms.java b/src/main/java/dev/aapy/ranks/type/LuckPerms.java new file mode 100644 index 0000000..0870f4e --- /dev/null +++ b/src/main/java/dev/aapy/ranks/type/LuckPerms.java @@ -0,0 +1,30 @@ +package dev.aapy.ranks.type; + +import dev.aapy.SnakeHub; +import dev.aapy.ranks.Permission; +import dev.aapy.util.CC; +import org.bukkit.OfflinePlayer; + + +public class LuckPerms implements Permission { + + @Override + public String getName(OfflinePlayer player) { + return CC.translate(SnakeHub.getInst().getManager().getPlugin().getPermission().getChat().getPrimaryGroup(String.valueOf(SnakeHub.getInst().getManager().getPlugin().getPermission().getPlugin().getServer().getWorlds().get(0).getName()), player)); + } + + @Override + public String getPrefix(OfflinePlayer player) { + return CC.translate(SnakeHub.getInst().getManager().getPlugin().getPermission().getChat().getPlayerPrefix(String.valueOf(SnakeHub.getInst().getManager().getPlugin().getPermission().getPlugin().getServer().getWorlds().get(0).getName()), player)); + } + + @Override + public String getSuffix(OfflinePlayer player) { + return CC.translate(SnakeHub.getInst().getManager().getPlugin().getPermission().getChat().getPlayerSuffix(String.valueOf(SnakeHub.getInst().getManager().getPlugin().getPermission().getPlugin().getServer().getWorlds().get(0).getName()), player)); + } + + @Override + public String getColor(OfflinePlayer player) { + return CC.translate(SnakeHub.getInst().getManager().getPlugin().getPermission().getChat().getPrimaryGroup(String.valueOf(SnakeHub.getInst().getManager().getPlugin().getPermission().getPlugin().getServer().getWorlds().get(0).getName()), player)); + } +} diff --git a/src/main/java/dev/aapy/scoreboard/ScoreBoardProvider.java b/src/main/java/dev/aapy/scoreboard/ScoreBoardProvider.java new file mode 100644 index 0000000..b730993 --- /dev/null +++ b/src/main/java/dev/aapy/scoreboard/ScoreBoardProvider.java @@ -0,0 +1,48 @@ +package dev.aapy.scoreboard; + +import dev.aapy.SnakeHub; +import dev.aapy.file.Config; +import dev.aapy.file.Scoreboard; +import dev.aapy.manager.managers.ScoreBoardManager; +import dev.aapy.scoreboard.assamble.AssembleAdapter; +import dev.aapy.util.CC; +import dev.aapy.util.SnakeUtil; +import me.clip.placeholderapi.PlaceholderAPI; +import org.apache.commons.lang.StringEscapeUtils; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author 7qv_ on 7/2/2022. + * @project SnakeHub + */ + +public class ScoreBoardProvider implements AssembleAdapter { + + private final ScoreBoardManager scoreboard = SnakeHub.getInst().getManager().getScoreboard(); + + @Override + public String getTitle(Player player) { + return Config.getConfig().getBoolean("BOOLEANS.SCOREBOARD.ANIMATED.TITLE") ? this.scoreboard.getScoreTitleTask().sendTitle() : CC.translate(Scoreboard.getConfig().getString("SCOREBOARD.TITLE")); + } + + @Override + public List getLines(Player player) { + final List list = new ArrayList<>(); + for (String lines : Scoreboard.getConfig().getStringList("SCOREBOARD.LINES")) { + lines = lines.replace("{arrow}", StringEscapeUtils.unescapeJava("\\u2a20")); + lines = lines.replace("{placeholder:date}", SnakeUtil.getDate()); + lines = lines.replace("{placeholder:time}", SnakeUtil.getHour()); + lines = lines.replace("{players_online}", Bukkit.getOnlinePlayers().size() + "/" + Bukkit.getServer().getMaxPlayers()); + lines = lines.replace("{rank}", SnakeHub.getInst().getPermission().getPermission().getPrefix(player)); + lines = lines.replace("{ign}", player.getName()); + lines = lines.replace("{footers}", Config.getConfig().getBoolean("BOOLEANS.SCOREBOARD.ANIMATED.FOOTER") ? this.scoreboard.getScoreTask().sendFooter() : CC.translate(Scoreboard.getConfig().getString("SCOREBOARD.FOOTER"))); + + list.add(PlaceholderAPI.setPlaceholders(player, lines)); + } + return list; + } +} \ No newline at end of file diff --git a/src/main/java/dev/aapy/scoreboard/assamble/Assemble.java b/src/main/java/dev/aapy/scoreboard/assamble/Assemble.java new file mode 100644 index 0000000..764545b --- /dev/null +++ b/src/main/java/dev/aapy/scoreboard/assamble/Assemble.java @@ -0,0 +1,115 @@ +package dev.aapy.scoreboard.assamble; + +import java.util.Map; +import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; + +import dev.aapy.scoreboard.events.AssembleBoardCreateEvent; +import lombok.Getter; +import lombok.Setter; + +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.entity.Player; +import org.bukkit.event.HandlerList; +import org.bukkit.plugin.java.JavaPlugin; + +@Getter @Setter +public class Assemble { + + private final JavaPlugin plugin; + + private AssembleAdapter adapter; + private AssembleThread thread; + private AssembleListener listeners; + private AssembleStyle assembleStyle = AssembleStyle.MODERN; + + private Map boards; + + private long ticks = 2; + private boolean hook = false, debugMode = true, callEvents = true; + + private final ChatColor[] chatColorCache = ChatColor.values(); + + /** + * Assemble. + * + * @param plugin instance. + * @param adapter that is being provided. + */ + public Assemble(JavaPlugin plugin, AssembleAdapter adapter) { + if (plugin == null) { + throw new RuntimeException("Assemble can not be instantiated without a plugin instance!"); + } + + this.plugin = plugin; + this.adapter = adapter; + this.boards = new ConcurrentHashMap<>(); + + this.setup(); + } + + /** + * Setup Assemble. + */ + public void setup() { + // Register Events. + this.listeners = new AssembleListener(this); + this.plugin.getServer().getPluginManager().registerEvents(listeners, this.plugin); + + // Ensure that the thread has stopped running. + if (this.thread != null) { + this.thread.stop(); + this.thread = null; + } + + // Register new boards for existing online players. + for (Player player : this.getPlugin().getServer().getOnlinePlayers()) { + + // Call Events if enabled. + if (this.isCallEvents()) { + AssembleBoardCreateEvent createEvent = new AssembleBoardCreateEvent(player); + + Bukkit.getPluginManager().callEvent(createEvent); + if (createEvent.isCancelled()) { + continue; + } + } + + getBoards().putIfAbsent(player.getUniqueId(), new AssembleBoard(player, this)); + } + + // Start Thread. + this.thread = new AssembleThread(this); + } + + /** + * Cleanup Assemble. + */ + public void cleanup() { + // Stop thread. + if (this.thread != null) { + this.thread.stop(); + this.thread = null; + } + + // Unregister listeners. + if (listeners != null) { + HandlerList.unregisterAll(listeners); + listeners = null; + } + + // Destroy player scoreboards. + for (UUID uuid : getBoards().keySet()) { + Player player = Bukkit.getPlayer(uuid); + + if (player == null || !player.isOnline()) { + continue; + } + + getBoards().remove(uuid); + player.setScoreboard(Bukkit.getScoreboardManager().getNewScoreboard()); + } + } + +} diff --git a/src/main/java/dev/aapy/scoreboard/assamble/AssembleAdapter.java b/src/main/java/dev/aapy/scoreboard/assamble/AssembleAdapter.java new file mode 100644 index 0000000..8ec5aee --- /dev/null +++ b/src/main/java/dev/aapy/scoreboard/assamble/AssembleAdapter.java @@ -0,0 +1,24 @@ +package dev.aapy.scoreboard.assamble; + +import java.util.List; +import org.bukkit.entity.Player; + +public interface AssembleAdapter { + + /** + * Get's the scoreboard title. + * + * @param player who's title is being displayed. + * @return title. + */ + String getTitle(Player player); + + /** + * Get's the scoreboard lines. + * + * @param player who's lines are being displayed. + * @return lines. + */ + List getLines(Player player); + +} diff --git a/src/main/java/dev/aapy/scoreboard/assamble/AssembleBoard.java b/src/main/java/dev/aapy/scoreboard/assamble/AssembleBoard.java new file mode 100644 index 0000000..3bfcb2a --- /dev/null +++ b/src/main/java/dev/aapy/scoreboard/assamble/AssembleBoard.java @@ -0,0 +1,130 @@ +package dev.aapy.scoreboard.assamble; + +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +import dev.aapy.scoreboard.events.AssembleBoardCreatedEvent; +import lombok.Getter; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.entity.Player; +import org.bukkit.scoreboard.DisplaySlot; +import org.bukkit.scoreboard.Objective; +import org.bukkit.scoreboard.Scoreboard; + +@Getter +public class AssembleBoard { + + private final Assemble assemble; + + private final List entries = new ArrayList<>(); + private final List identifiers = new ArrayList<>(); + + private final UUID uuid; + + /** + * Assemble Board. + * + * @param player that the board belongs to. + * @param assemble instance. + */ + public AssembleBoard(Player player, Assemble assemble) { + this.uuid = player.getUniqueId(); + this.assemble = assemble; + this.setup(player); + } + + /** + * Get's a player's bukkit scoreboard. + * + * @return either existing scoreboard or new scoreboard. + */ + public Scoreboard getScoreboard() { + Player player = Bukkit.getPlayer(getUuid()); + if (getAssemble().isHook() || player.getScoreboard() != Bukkit.getScoreboardManager().getMainScoreboard()) { + return player.getScoreboard(); + } else { + return Bukkit.getScoreboardManager().getNewScoreboard(); + } + } + + /** + * Get's the player's scoreboard objective. + * + * @return either existing objecting or new objective. + */ + public Objective getObjective() { + Scoreboard scoreboard = getScoreboard(); + if (scoreboard.getObjective("Assemble") == null) { + Objective objective = scoreboard.registerNewObjective("Assemble", "dummy"); + objective.setDisplaySlot(DisplaySlot.SIDEBAR); + objective.setDisplayName(getAssemble().getAdapter().getTitle(Bukkit.getPlayer(getUuid()))); + return objective; + } else { + return scoreboard.getObjective("Assemble"); + } + } + + /** + * Setup the board. + * + * @param player who's board to setup. + */ + private void setup(Player player) { + Scoreboard scoreboard = getScoreboard(); + player.setScoreboard(scoreboard); + getObjective(); + + // Call Events if enabled. + if (assemble.isCallEvents()) { + AssembleBoardCreatedEvent createdEvent = new AssembleBoardCreatedEvent(this); + Bukkit.getPluginManager().callEvent(createdEvent); + } + } + + /** + * Get the board entry at a specific position. + * + * @param pos to find entry. + * @return entry if it isn't out of range. + */ + public AssembleBoardEntry getEntryAtPosition(int pos) { + return pos >= this.entries.size() ? null : this.entries.get(pos); + } + + /** + * Get the unique identifier for position in scoreboard. + * + * @param position for identifier. + * @return unique identifier. + */ + public String getUniqueIdentifier(int position) { + String identifier = getRandomChatColor(position) + ChatColor.WHITE; + + while (this.identifiers.contains(identifier)) { + identifier = identifier + getRandomChatColor(position) + ChatColor.WHITE; + } + + // This is rare, but just in case, make the method recursive + if (identifier.length() > 16) { + return this.getUniqueIdentifier(position); + } + + // Add our identifier to the list so there are no duplicates + this.identifiers.add(identifier); + + return identifier; + } + + /** + * Gets a ChatColor based off the position in the collection. + * + * @param position of entry. + * @return ChatColor adjacent to position. + */ + private String getRandomChatColor(int position) { + return assemble.getChatColorCache()[position].toString(); + } + +} diff --git a/src/main/java/dev/aapy/scoreboard/assamble/AssembleBoardEntry.java b/src/main/java/dev/aapy/scoreboard/assamble/AssembleBoardEntry.java new file mode 100644 index 0000000..42b40d7 --- /dev/null +++ b/src/main/java/dev/aapy/scoreboard/assamble/AssembleBoardEntry.java @@ -0,0 +1,91 @@ +package dev.aapy.scoreboard.assamble; + +import org.bukkit.scoreboard.Scoreboard; +import org.bukkit.scoreboard.Team; + +import lombok.Setter; + +public class AssembleBoardEntry { + + private final AssembleBoard board; + + private Team team; + @Setter + private String text, identifier; + + /** + * Assemble Board Entry + * + * @param board that entry belongs to. + * @param text of entry. + * @param position of entry. + */ + public AssembleBoardEntry(AssembleBoard board, String text, int position) { + this.board = board; + this.text = text; + this.identifier = this.board.getUniqueIdentifier(position); + + this.setup(); + } + + /** + * Setup Board Entry. + */ + public void setup() { + final Scoreboard scoreboard = this.board.getScoreboard(); + + if (scoreboard == null) { + return; + } + + String teamName = this.identifier; + + // This shouldn't happen, but just in case. + if (teamName.length() > 16) { + teamName = teamName.substring(0, 16); + } + + Team team = scoreboard.getTeam(teamName); + + // Register the team if it does not exist. + if (team == null) { + team = scoreboard.registerNewTeam(teamName); + } + + // Add the entry to the team. + if (!team.getEntries().contains(this.identifier)) { + team.addEntry(this.identifier); + } + + // Add the entry if it does not exist. + if (!this.board.getEntries().contains(this)) { + this.board.getEntries().add(this); + } + + this.team = team; + } + + /** + * Send Board Entry Update. + * + * @param position of entry. + */ + public void send(int position) { + // Set Prefix & Suffix. + String[] split = AssembleUtils.splitTeamText(text); + this.team.setPrefix(split[0]); + this.team.setSuffix(split[1]); + + // Set the score + this.board.getObjective().getScore(this.identifier).setScore(position); + } + + /** + * Remove Board Entry from Board. + */ + public void remove() { + this.board.getIdentifiers().remove(this.identifier); + this.board.getScoreboard().resetScores(this.identifier); + } + +} diff --git a/src/main/java/dev/aapy/scoreboard/assamble/AssembleException.java b/src/main/java/dev/aapy/scoreboard/assamble/AssembleException.java new file mode 100644 index 0000000..4c0e87e --- /dev/null +++ b/src/main/java/dev/aapy/scoreboard/assamble/AssembleException.java @@ -0,0 +1,14 @@ +package dev.aapy.scoreboard.assamble; + +public class AssembleException extends RuntimeException { + + /** + * Assemble Exception. + * + * @param message attributed to exception. + */ + public AssembleException(String message) { + super(message); + } + +} diff --git a/src/main/java/dev/aapy/scoreboard/assamble/AssembleListener.java b/src/main/java/dev/aapy/scoreboard/assamble/AssembleListener.java new file mode 100644 index 0000000..9a5d042 --- /dev/null +++ b/src/main/java/dev/aapy/scoreboard/assamble/AssembleListener.java @@ -0,0 +1,57 @@ +package dev.aapy.scoreboard.assamble; + +import dev.aapy.scoreboard.events.AssembleBoardCreateEvent; +import dev.aapy.scoreboard.events.AssembleBoardDestroyEvent; +import lombok.Getter; +import org.bukkit.Bukkit; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.event.player.PlayerQuitEvent; + +@Getter +public class AssembleListener implements Listener { + + private final Assemble assemble; + + /** + * Assemble Listener. + * + * @param assemble instance. + */ + public AssembleListener(Assemble assemble) { + this.assemble = assemble; + } + + @EventHandler + public void onPlayerJoin(PlayerJoinEvent event) { + // Call Events if enabled. + if (assemble.isCallEvents()) { + AssembleBoardCreateEvent createEvent = new AssembleBoardCreateEvent(event.getPlayer()); + + Bukkit.getPluginManager().callEvent(createEvent); + if (createEvent.isCancelled()) { + return; + } + } + + getAssemble().getBoards().put(event.getPlayer().getUniqueId(), new AssembleBoard(event.getPlayer(), getAssemble())); + } + + @EventHandler + public void onPlayerQuit(PlayerQuitEvent event) { + // Call Events if enabled. + if (assemble.isCallEvents()) { + AssembleBoardDestroyEvent destroyEvent = new AssembleBoardDestroyEvent(event.getPlayer()); + + Bukkit.getPluginManager().callEvent(destroyEvent); + if (destroyEvent.isCancelled()) { + return; + } + } + + getAssemble().getBoards().remove(event.getPlayer().getUniqueId()); + event.getPlayer().setScoreboard(Bukkit.getScoreboardManager().getMainScoreboard()); + } + +} diff --git a/src/main/java/dev/aapy/scoreboard/assamble/AssembleStyle.java b/src/main/java/dev/aapy/scoreboard/assamble/AssembleStyle.java new file mode 100644 index 0000000..73a6987 --- /dev/null +++ b/src/main/java/dev/aapy/scoreboard/assamble/AssembleStyle.java @@ -0,0 +1,38 @@ +package dev.aapy.scoreboard.assamble; + +import lombok.Getter; + +@Getter +public enum AssembleStyle { + + KOHI(true, 15), VIPER(true, -1), MODERN(false, 1), CUSTOM(false, 0); + + private boolean descending; + private int startNumber; + + /** + * Assemble Style. + * + * @param descending whether the positions are going down or up. + * @param startNumber from where to loop from. + */ + AssembleStyle(boolean descending, int startNumber) { + this.descending = descending; + this.startNumber = startNumber; + } + + public AssembleStyle reverse() { + return descending(!this.descending); + } + + public AssembleStyle descending(boolean descending) { + this.descending = descending; + return this; + } + + public AssembleStyle startNumber(int startNumber) { + this.startNumber = startNumber; + return this; + } + +} diff --git a/src/main/java/dev/aapy/scoreboard/assamble/AssembleThread.java b/src/main/java/dev/aapy/scoreboard/assamble/AssembleThread.java new file mode 100644 index 0000000..93222fe --- /dev/null +++ b/src/main/java/dev/aapy/scoreboard/assamble/AssembleThread.java @@ -0,0 +1,127 @@ +package dev.aapy.scoreboard.assamble; + +import org.bukkit.ChatColor; +import org.bukkit.entity.Player; +import org.bukkit.scoreboard.Objective; +import org.bukkit.scoreboard.Scoreboard; + +import java.util.Collections; +import java.util.List; + +public class AssembleThread extends Thread { + + private final Assemble assemble; + + /** + * Assemble Thread. + * + * @param assemble instance. + */ + AssembleThread(Assemble assemble) { + this.assemble = assemble; + this.start(); + } + + @Override + public void run() { + while(true) { + try { + tick(); + sleep(assemble.getTicks() * 50); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + + /** + * Tick logic for thread. + */ + private void tick() { + for (Player player : this.assemble.getPlugin().getServer().getOnlinePlayers()) { + try { + AssembleBoard board = this.assemble.getBoards().get(player.getUniqueId()); + + // This shouldn't happen, but just in case. + if (board == null) { + continue; + } + + Scoreboard scoreboard = board.getScoreboard(); + Objective objective = board.getObjective(); + + if (scoreboard == null || objective == null) { + continue; + } + + // Just make a variable so we don't have to + // process the same thing twice. + String title = ChatColor.translateAlternateColorCodes('&', this.assemble.getAdapter().getTitle(player)); + + // Update the title if needed. + if (!objective.getDisplayName().equals(title)) { + objective.setDisplayName(title); + } + + List newLines = this.assemble.getAdapter().getLines(player); + + // Allow adapter to return null/empty list to display nothing. + if (newLines == null || newLines.isEmpty()) { + board.getEntries().forEach(AssembleBoardEntry::remove); + board.getEntries().clear(); + } else { + if (newLines.size() > 15) { + newLines = newLines.subList(0, 15); + } + + // Reverse the lines because scoreboard scores are in descending order. + if (!this.assemble.getAssembleStyle().isDescending()) { + Collections.reverse(newLines); + } + + // Remove excessive amount of board entries. + if (board.getEntries().size() > newLines.size()) { + for (int i = newLines.size(); i < board.getEntries().size(); i++) { + AssembleBoardEntry entry = board.getEntryAtPosition(i); + + if (entry != null) { + entry.remove(); + } + } + } + + // Update existing entries / add new entries. + int cache = this.assemble.getAssembleStyle().getStartNumber(); + for (int i = 0; i < newLines.size(); i++) { + AssembleBoardEntry entry = board.getEntryAtPosition(i); + + // Translate any colors. + String line = ChatColor.translateAlternateColorCodes('&', newLines.get(i)); + + // If the entry is null, just create a new one. + // Creating a new AssembleBoardEntry instance will add + // itself to the provided board's entries list. + if (entry == null) { + entry = new AssembleBoardEntry(board, line, i); + } + + // Update text, setup the team, and update the display values. + entry.setText(line); + entry.setup(); + entry.send( + this.assemble.getAssembleStyle().isDescending() ? cache-- : cache++ + ); + } + } + + if (player.getScoreboard() != scoreboard && !assemble.isHook()) { + player.setScoreboard(scoreboard); + } + } catch(Exception e) { + e.printStackTrace(); + throw new AssembleException("There was an error updating " + player.getName() + "'s scoreboard."); + } + } + } + +} diff --git a/src/main/java/dev/aapy/scoreboard/assamble/AssembleUtils.java b/src/main/java/dev/aapy/scoreboard/assamble/AssembleUtils.java new file mode 100644 index 0000000..c7849f1 --- /dev/null +++ b/src/main/java/dev/aapy/scoreboard/assamble/AssembleUtils.java @@ -0,0 +1,35 @@ +package dev.aapy.scoreboard.assamble; + +import org.bukkit.ChatColor; + +public class AssembleUtils { + + public static String[] splitTeamText(String input) { + final int inputLength = input.length(); + if (inputLength > 16) { + // Make the prefix the first 16 characters of our text + String prefix = input.substring(0, 16); + + // Get the last index of the color char in the prefix + final int lastColorIndex = prefix.lastIndexOf(ChatColor.COLOR_CHAR); + + String suffix; + + if (lastColorIndex >= 14) { + prefix = prefix.substring(0, lastColorIndex); + suffix = ChatColor.getLastColors(input.substring(0, 17)) + input.substring(lastColorIndex + 2); + } else { + suffix = ChatColor.getLastColors(prefix) + input.substring(16); + } + + if (suffix.length() > 16) { + suffix = suffix.substring(0, 16); + } + + return new String[] {prefix, suffix}; + } else { + return new String[] {input, ""}; + } + } + +} diff --git a/src/main/java/dev/aapy/scoreboard/events/AssembleBoardCreateEvent.java b/src/main/java/dev/aapy/scoreboard/events/AssembleBoardCreateEvent.java new file mode 100644 index 0000000..561bdd1 --- /dev/null +++ b/src/main/java/dev/aapy/scoreboard/events/AssembleBoardCreateEvent.java @@ -0,0 +1,31 @@ +package dev.aapy.scoreboard.events; + +import lombok.Getter; +import lombok.Setter; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +@Getter @Setter +public class AssembleBoardCreateEvent extends Event implements Cancellable { + + @Getter public static HandlerList handlerList = new HandlerList(); + + private Player player; + private boolean cancelled = false; + + /** + * Assemble Board Create Event. + * + * @param player that the board is being created for. + */ + public AssembleBoardCreateEvent(Player player) { + this.player = player; + } + + @Override + public HandlerList getHandlers() { + return handlerList; + } +} diff --git a/src/main/java/dev/aapy/scoreboard/events/AssembleBoardCreatedEvent.java b/src/main/java/dev/aapy/scoreboard/events/AssembleBoardCreatedEvent.java new file mode 100644 index 0000000..81fd7bd --- /dev/null +++ b/src/main/java/dev/aapy/scoreboard/events/AssembleBoardCreatedEvent.java @@ -0,0 +1,30 @@ +package dev.aapy.scoreboard.events; + +import dev.aapy.scoreboard.assamble.AssembleBoard; +import lombok.Getter; +import lombok.Setter; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +@Getter @Setter +public class AssembleBoardCreatedEvent extends Event { + + @Getter public static HandlerList handlerList = new HandlerList(); + + private boolean cancelled = false; + private final AssembleBoard board; + + /** + * Assemble Board Created Event. + * + * @param board of player. + */ + public AssembleBoardCreatedEvent(AssembleBoard board) { + this.board = board; + } + + @Override + public HandlerList getHandlers() { + return handlerList; + } +} diff --git a/src/main/java/dev/aapy/scoreboard/events/AssembleBoardDestroyEvent.java b/src/main/java/dev/aapy/scoreboard/events/AssembleBoardDestroyEvent.java new file mode 100644 index 0000000..fa3a601 --- /dev/null +++ b/src/main/java/dev/aapy/scoreboard/events/AssembleBoardDestroyEvent.java @@ -0,0 +1,31 @@ +package dev.aapy.scoreboard.events; + +import lombok.Getter; +import lombok.Setter; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +@Getter @Setter +public class AssembleBoardDestroyEvent extends Event implements Cancellable { + + @Getter public static HandlerList handlerList = new HandlerList(); + + private Player player; + private boolean cancelled = false; + + /** + * Assemble Board Destroy Event. + * + * @param player who's board got destroyed. + */ + public AssembleBoardDestroyEvent(Player player) { + this.player = player; + } + + @Override + public HandlerList getHandlers() { + return handlerList; + } +} diff --git a/src/main/java/dev/aapy/tablist/PlayerTablist.java b/src/main/java/dev/aapy/tablist/PlayerTablist.java new file mode 100644 index 0000000..37de8d1 --- /dev/null +++ b/src/main/java/dev/aapy/tablist/PlayerTablist.java @@ -0,0 +1,191 @@ +package dev.aapy.tablist; + +import dev.aapy.tablist.impl.v1_7TabImpl; +import dev.aapy.tablist.playerversion.PlayerVersion; +import dev.aapy.tablist.playerversion.PlayerVersionHandler; +import dev.aapy.tablist.skin.Skin; +import dev.aapy.tablist.utils.LegacyClient; +import lombok.Getter; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.entity.Player; +import org.bukkit.scheduler.BukkitRunnable; +import org.bukkit.scoreboard.Scoreboard; +import org.bukkit.scoreboard.Team; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +@Getter +public class PlayerTablist { + + private final Player player; + private Scoreboard scoreboard; + private int lastHeaderFooter; + + private final Set currentEntrySet = new HashSet<>(); + + @SuppressWarnings("deprecation") + public PlayerTablist(Player player) { + this.player = player; + + scoreboard = Bukkit.getScoreboardManager().getNewScoreboard(); + + //Scoreboard + if (!this.player.getScoreboard().equals(Bukkit.getScoreboardManager().getMainScoreboard())) { + scoreboard = player.getScoreboard(); + } + + player.setScoreboard(scoreboard); + + this.setup(); + Team team1 = player.getScoreboard().getTeam("\\u000181"); + if (team1 == null) { + team1 = player.getScoreboard().registerNewTeam("\\u000181"); + } + team1.addEntry(player.getName()); + for (Player loopPlayer : Bukkit.getServer().getOnlinePlayers()) { + Team team = loopPlayer.getScoreboard().getTeam("\\u000181"); + if (team == null) { + team = loopPlayer.getScoreboard().registerNewTeam("\\u000181"); + } + team.addEntry(player.getName()); + team.addEntry(loopPlayer.getName()); + team1.addEntry(loopPlayer.getName()); + team1.addEntry(player.getName()); + } + } + + public static String[] splitStrings(String text, int rawSlot) { + if (text.length() > 16) { + String prefix = text.substring(0, 16); + String suffix; + + if (prefix.charAt(15) == ChatColor.COLOR_CHAR || prefix.charAt(15) == '&') { + prefix = prefix.substring(0, 15); + suffix = text.substring(15); + } else if (prefix.charAt(14) == ChatColor.COLOR_CHAR || prefix.charAt(14) == '&') { + prefix = prefix.substring(0, 14); + suffix = text.substring(14); + } else { + suffix = ChatColor.getLastColors(ChatColor.translateAlternateColorCodes('&', prefix)) + text.substring(16); + } + + if (suffix.length() > 16) { + suffix = suffix.substring(0, 16); + } + + return new String[]{ + prefix, + suffix + }; + } else { + return new String[]{ + text + }; + } + } + + private void setup() { + final int possibleSlots = (PlayerVersionHandler.getPlayerVersion(player) == PlayerVersion.v1_7 ? 60 : 80); + for (int i = 1; i <= possibleSlots; i++) { + final TabColumn tabColumn = TabColumn.getFromSlot(player, i); + if (tabColumn == null) { + continue; + } + TabEntry tabEntry = Tab.getInstance().getImplementation().createFakePlayer( + this, + "0" + (i > 9 ? i : "0" + i) + "|Tab", + tabColumn, + tabColumn.getNumb(player, i), + i + ); + if (Bukkit.getPluginManager().getPlugin("Featherboard") == null + && (PlayerVersionHandler.version.getPlayerVersion(player) == PlayerVersion.v1_7 + || Tab.getInstance().getImplementation() instanceof v1_7TabImpl)) { + Team team = player.getScoreboard().getTeam(LegacyClient.NAMES.get(i - 1)); + if (team != null) { + team.unregister(); + } + team = player.getScoreboard().registerNewTeam(LegacyClient.NAMES.get(i - 1)); + team.setPrefix(""); + team.setSuffix(""); + + team.addEntry(LegacyClient.ENTRY.get(i - 1)); + + } + currentEntrySet.add(tabEntry); + } + + if (Bukkit.getPluginManager().getPlugin("Featherboard") != null) { + new BukkitRunnable() { + @Override + public void run() { + for (int i = 1; i <= possibleSlots; i++) { + if (PlayerVersionHandler.version.getPlayerVersion(player) == PlayerVersion.v1_7 || Tab.getInstance().getImplementation() instanceof v1_7TabImpl) { + Team team = player.getScoreboard().getTeam(LegacyClient.NAMES.get(i - 1)); + if (team != null) { + team.unregister(); + } + team = player.getScoreboard().registerNewTeam(LegacyClient.NAMES.get(i - 1)); + team.setPrefix(""); + team.setSuffix(""); + + team.addEntry(LegacyClient.ENTRY.get(i - 1)); + + } + } + } + }.runTaskLater(Tab.getInstance().getPlugin(), 40); + } + } + + public void update() { + if (PlayerVersionHandler.getPlayerVersion(player) != PlayerVersion.v1_7) { + List header = Tab.getInstance().getProvider().getHeader(player); + List footer = Tab.getInstance().getProvider().getFooter(player); + + int headerFooter = header.hashCode() + footer.hashCode(); + + if (headerFooter != lastHeaderFooter) { + lastHeaderFooter = headerFooter; + Tab.getInstance().getImplementation().updateHeaderAndFooter(player, header, footer); + } + } + + + Set lastSet = new HashSet<>(currentEntrySet); + for (TabLayout layout : Tab.getInstance().getProvider().getProvider(player)) { + TabEntry tabEntry = getEntry(layout.getColumn(), layout.getSlot()); + if (tabEntry != null) { + lastSet.remove(tabEntry); + Tab.getInstance().getImplementation().updateFakeName(this, tabEntry, layout.getText()); + Tab.getInstance().getImplementation().updateFakeLatency(this, tabEntry, layout.getPing()); + if (PlayerVersionHandler.getPlayerVersion(player) != PlayerVersion.v1_7) { + if (layout.getSkin() != null || !tabEntry.getSkin().equals(layout.getSkin())) { + + Tab.getInstance().getImplementation().updateFakeSkin(this, tabEntry, layout.getSkin()); + } + } + } + } + for (TabEntry tabEntry : lastSet) { + Tab.getInstance().getImplementation().updateFakeName(this, tabEntry, ""); + Tab.getInstance().getImplementation().updateFakeLatency(this, tabEntry, -1); + if (PlayerVersionHandler.getPlayerVersion(player) != PlayerVersion.v1_7) { + Tab.getInstance().getImplementation().updateFakeSkin(this, tabEntry, Skin.DEFAULT); + } + } + lastSet.clear(); + } + + public TabEntry getEntry(TabColumn column, Integer slot) { + for (TabEntry entry : currentEntrySet) { + if (entry.getColumn().name().equalsIgnoreCase(column.name()) && entry.getSlot() == slot) { + return entry; + } + } + return null; + } +} diff --git a/src/main/java/dev/aapy/tablist/Tab.java b/src/main/java/dev/aapy/tablist/Tab.java new file mode 100644 index 0000000..28a6e4d --- /dev/null +++ b/src/main/java/dev/aapy/tablist/Tab.java @@ -0,0 +1,92 @@ +package dev.aapy.tablist; + +import dev.aapy.tablist.impl.v1_7TabImpl; +import dev.aapy.tablist.impl.v1_8TabImpl; +import dev.aapy.tablist.playerversion.PlayerVersionHandler; +import lombok.Getter; +import org.bukkit.Bukkit; +import org.bukkit.event.HandlerList; +import org.bukkit.plugin.java.JavaPlugin; + +import java.util.Map; +import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; + +@Getter +public class Tab { + + @Getter + private static Tab instance; + + private final JavaPlugin plugin; + private final TabProvider provider; + private final Map tablists; + private TabThread thread; + private TabNMS implementation; + private TabListener listeners; + + + public Tab(JavaPlugin plugin, TabProvider provider) { + instance = this; + + this.plugin = plugin; + this.provider = provider; + this.tablists = new ConcurrentHashMap<>(); + + new PlayerVersionHandler(); + + this.registerImplementation(); + + this.setup(); + } + + private void registerImplementation() { + String serverVersion = Bukkit.getServer().getClass().getPackage().getName().split("\\.")[3]; + + if (serverVersion.equalsIgnoreCase("v1_7_R4")) { + this.implementation = new v1_7TabImpl(); + System.out.println("Registered Implementation with 1.7 Tab"); + return; + } + if (serverVersion.equalsIgnoreCase("v1_8_R3")) { + this.implementation = new v1_8TabImpl(); + System.out.println("Registered Implementation with 1.8 Tab"); + return; + } + + if (Bukkit.getPluginManager().getPlugin("ProtocolLib") != null) { + plugin.getLogger().info("Registered Implementation with ProtocolLib"); + return; + } + + } + + @SuppressWarnings("deprecation") + private void setup() { + listeners = new TabListener(); + //Register Events + this.plugin.getServer().getPluginManager().registerEvents(listeners, this.plugin); + + //Ensure that the thread has stopped running + if (this.thread != null) { + this.thread.stop(); + this.thread = null; + } + + //Start Thread + this.thread = new TabThread(this); + } + + @SuppressWarnings("deprecation") + public void disable() { + if (this.thread != null) { + this.thread.stop(); + this.thread = null; + } + + if (listeners != null) { + HandlerList.unregisterAll(listeners); + listeners = null; + } + } +} diff --git a/src/main/java/dev/aapy/tablist/TabColumn.java b/src/main/java/dev/aapy/tablist/TabColumn.java new file mode 100644 index 0000000..d8614f3 --- /dev/null +++ b/src/main/java/dev/aapy/tablist/TabColumn.java @@ -0,0 +1,105 @@ +package dev.aapy.tablist; + + +import dev.aapy.tablist.playerversion.PlayerVersion; +import dev.aapy.tablist.playerversion.PlayerVersionHandler; +import lombok.Getter; +import org.bukkit.entity.Player; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +@Getter +public enum TabColumn { + + LEFT(0, "Left", -2, 1, 3), + MIDDLE(1, "Middle", -1, 21, 3), + RIGHT(2, "Right", 0, 41, 3), + /** + * Far Right Column + * Note: This Column is only visible on 1.8+ player versions. + */ + FAR_RIGHT(3, "Far-Right", 60, 61, 1); + + private final int startNumber; + private final int incrementBy; + private final int rawStart; + private final List numbers = new ArrayList<>(); + private final String identifier; + private final int ordinal; + + TabColumn(int ordinal, String identifier, int rawStart, int startNumber, int incrementBy) { + this.ordinal = ordinal; + this.identifier = identifier; + this.rawStart = rawStart; + this.startNumber = startNumber; + this.incrementBy = incrementBy; + generate(); + } + + public static TabColumn getColumn(String identifier) { + for (TabColumn tabColumn : TabColumn.values()) { + if (tabColumn.getIdentifier().equalsIgnoreCase(identifier)) { + return tabColumn; + } + } + return null; + } + + private static boolean isBetween(int input, int min, int max) { + return input >= min && input <= max; + } + + public static TabColumn getFromSlot(Player player, Integer slot) { + /* Player Version 1.7 */ + if (PlayerVersionHandler.getPlayerVersion(player) == PlayerVersion.v1_7) { + return Arrays.stream(TabColumn.values()) + .filter(tabColumn -> tabColumn.getNumbers().contains(slot)) + .findFirst().get(); + /* Player Version 1.8+ */ + } else { + /* Left Column */ + if (isBetween(slot, 1, 20)) return LEFT; + /* Middle Column */ + if (isBetween(slot, 21, 40)) return MIDDLE; + /* Right Column */ + if (isBetween(slot, 41, 60)) return RIGHT; + /* Far Right Column */ + if (isBetween(slot, 61, 80)) return FAR_RIGHT; + return null; + } + } + + public static TabColumn getFromOrdinal(int ordinal) { + for (TabColumn column : TabColumn.values()) { + if (column.getOrdinal() == ordinal) { + return column; + } + } + return null; + } + + private void generate() { + for (int i = 1; i <= 20; i++) { + Integer numb = rawStart + (i * incrementBy); + this.numbers.add(numb); + } + } + + public Integer getNumb(Player player, int raw) { + /* Check if the Player is not a 1.7 User */ + if (PlayerVersionHandler.getPlayerVersion(player) != PlayerVersion.v1_7) { + return raw - startNumber + 1; + } + int number = 0; + for (int integer : numbers) { + number++; + if (integer == raw) { + return number; + } + } + return number; + } +} + diff --git a/src/main/java/dev/aapy/tablist/TabEntry.java b/src/main/java/dev/aapy/tablist/TabEntry.java new file mode 100644 index 0000000..d5774bf --- /dev/null +++ b/src/main/java/dev/aapy/tablist/TabEntry.java @@ -0,0 +1,25 @@ +package dev.aapy.tablist; + + +import dev.aapy.tablist.skin.Skin; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.Setter; +import org.bukkit.OfflinePlayer; + +@Getter +@Setter +@AllArgsConstructor +public class TabEntry { + + private String id; + private OfflinePlayer offlinePlayer; + private String text; + private PlayerTablist tab; + private Skin skin; + private TabColumn column; + private int slot; + private int rawSlot; + private int latency; + +} diff --git a/src/main/java/dev/aapy/tablist/TabLayout.java b/src/main/java/dev/aapy/tablist/TabLayout.java new file mode 100644 index 0000000..78de357 --- /dev/null +++ b/src/main/java/dev/aapy/tablist/TabLayout.java @@ -0,0 +1,43 @@ +package dev.aapy.tablist; + +import dev.aapy.tablist.skin.Skin; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class TabLayout { + + private TabColumn column = TabColumn.LEFT; + private int ping = 0; + private int slot = 1; + private String text = ""; + private Skin skin = Skin.DEFAULT; + + + public TabLayout text(String text) { + this.text = text; + return this; + } + + public TabLayout skin(Skin skin) { + this.skin = skin; + return this; + } + + public TabLayout slot(Integer slot) { + this.slot = slot; + return this; + } + + public TabLayout ping(Integer ping) { + this.ping = ping; + return this; + } + + public TabLayout column(TabColumn tabColumn) { + this.column = tabColumn; + return this; + } + +} diff --git a/src/main/java/dev/aapy/tablist/TabListener.java b/src/main/java/dev/aapy/tablist/TabListener.java new file mode 100644 index 0000000..18840e0 --- /dev/null +++ b/src/main/java/dev/aapy/tablist/TabListener.java @@ -0,0 +1,47 @@ +package dev.aapy.tablist; + +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.event.player.PlayerKickEvent; +import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.event.server.PluginDisableEvent; +import org.bukkit.scoreboard.Team; + +public class TabListener implements Listener { + + @EventHandler(priority = EventPriority.MONITOR) + public void onJoin(PlayerJoinEvent event) { + final Player player = event.getPlayer(); + + Tab.getInstance().getTablists().put(player.getUniqueId(), new PlayerTablist(event.getPlayer())); + } + + + private void handleDisconnect(Player player) { + Team team = player.getScoreboard().getTeam("\\u000181"); + if (team != null) { + team.unregister(); + } + + Tab.getInstance().getTablists().remove(player.getUniqueId()); + } + + @EventHandler(priority = EventPriority.LOWEST) + public void onPlayerQuit(PlayerQuitEvent event) { + handleDisconnect(event.getPlayer()); + } + + @EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST) + public void onPlayerKick(PlayerKickEvent event) { + handleDisconnect(event.getPlayer()); + } + + + @EventHandler + public void onPluginDisable(PluginDisableEvent event) { + Tab.getInstance().disable(); + } +} diff --git a/src/main/java/dev/aapy/tablist/TabNMS.java b/src/main/java/dev/aapy/tablist/TabNMS.java new file mode 100644 index 0000000..3cc86e2 --- /dev/null +++ b/src/main/java/dev/aapy/tablist/TabNMS.java @@ -0,0 +1,33 @@ +package dev.aapy.tablist; + +import dev.aapy.tablist.skin.Skin; +import org.bukkit.entity.Player; + +import java.util.List; + +public interface TabNMS { + + TabEntry createFakePlayer( + PlayerTablist playerTablist, String string, TabColumn column, Integer slot, Integer rawSlot + ); + + void updateFakeName( + PlayerTablist playerTablist, TabEntry tabEntry, String text + ); + + void updateFakeLatency( + PlayerTablist playerTablist, TabEntry tabEntry, Integer latency + ); + + void updateFakeSkin( + PlayerTablist playerTablist, TabEntry tabEntry, Skin skin + ); + + void updateHeaderAndFooter( + Player player, List header, List footer + ); + + Skin getSkin( + Player player); + +} diff --git a/src/main/java/dev/aapy/tablist/TabProvider.java b/src/main/java/dev/aapy/tablist/TabProvider.java new file mode 100644 index 0000000..bf525de --- /dev/null +++ b/src/main/java/dev/aapy/tablist/TabProvider.java @@ -0,0 +1,17 @@ +package dev.aapy.tablist; + +import org.bukkit.entity.Player; + +import java.util.List; +import java.util.Set; + + +public interface TabProvider { + + Set getProvider(Player player); + + List getFooter(Player player); + + List getHeader(Player player); + +} diff --git a/src/main/java/dev/aapy/tablist/TabThread.java b/src/main/java/dev/aapy/tablist/TabThread.java new file mode 100644 index 0000000..00c2918 --- /dev/null +++ b/src/main/java/dev/aapy/tablist/TabThread.java @@ -0,0 +1,35 @@ +package dev.aapy.tablist; + +public class TabThread extends Thread { + + private final Tab htab; + + public TabThread(Tab htab) { + this.htab = htab; + this.start(); + } + + @Override + public void run() { + while (true) { + //Tick + try { + tick(); + } catch (NullPointerException e) { + e.printStackTrace(); + } + //Thread Sleep + try { + sleep(250L); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + + private void tick() { + for (PlayerTablist tablist : htab.getTablists().values()) { + tablist.update(); + } + } +} diff --git a/src/main/java/dev/aapy/tablist/impl/v1_7TabImpl.java b/src/main/java/dev/aapy/tablist/impl/v1_7TabImpl.java new file mode 100644 index 0000000..06d1371 --- /dev/null +++ b/src/main/java/dev/aapy/tablist/impl/v1_7TabImpl.java @@ -0,0 +1,300 @@ +package dev.aapy.tablist.impl; + +import dev.aapy.tablist.utils.CC; +import dev.aapy.tablist.utils.Reflection; +import dev.aapy.tablist.PlayerTablist; +import dev.aapy.tablist.TabColumn; +import dev.aapy.tablist.TabEntry; +import dev.aapy.tablist.TabNMS; +import dev.aapy.tablist.playerversion.PlayerVersion; +import dev.aapy.tablist.playerversion.PlayerVersionHandler; +import dev.aapy.tablist.skin.Skin; +import dev.aapy.tablist.utils.LegacyClient; +import net.minecraft.server.v1_7_R4.*; +import net.minecraft.util.com.mojang.authlib.GameProfile; +import net.minecraft.util.com.mojang.authlib.properties.Property; +import org.apache.commons.lang.StringEscapeUtils; +import org.bukkit.ChatColor; +import org.bukkit.Location; +import org.bukkit.OfflinePlayer; +import org.bukkit.craftbukkit.v1_7_R4.entity.CraftPlayer; +import org.bukkit.entity.Player; +import org.bukkit.scoreboard.Team; +import org.spigotmc.ProtocolInjector; + +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.util.List; +import java.util.Map; +import java.util.UUID; + + +public class v1_7TabImpl implements TabNMS { + + private static final MinecraftServer server = MinecraftServer.getServer(); + private static final WorldServer world = server.getWorldServer(0); + private static final PlayerInteractManager manager = new PlayerInteractManager(world); + + public v1_7TabImpl() { + } + + @Override + public TabEntry createFakePlayer(PlayerTablist playerTablist, String string, TabColumn column, Integer slot, Integer rawSlot) { + final OfflinePlayer offlinePlayer = new OfflinePlayer() { + private final UUID uuid = UUID.randomUUID(); + + @Override + public boolean isOnline() { + return true; + } + + @Override + public String getName() { + return string; + } + + @Override + public UUID getUniqueId() { + return uuid; + } + + @Override + public boolean isBanned() { + return false; + } + + @Override + public void setBanned(boolean b) { + + } + + @Override + public boolean isWhitelisted() { + return false; + } + + @Override + public void setWhitelisted(boolean b) { + + } + + @Override + public Player getPlayer() { + return null; + } + + @Override + public long getFirstPlayed() { + return 0; + } + + @Override + public long getLastPlayed() { + return 0; + } + + + @Override + public boolean hasPlayedBefore() { + return false; + } + + @Override + public Location getBedSpawnLocation() { + return null; + } + + @Override + public Map serialize() { + return null; + } + + @Override + public boolean isOp() { + return false; + } + + @Override + public void setOp(boolean b) { + + } + }; + final Player player = playerTablist.getPlayer(); + final PlayerVersion playerVersion = PlayerVersionHandler.getPlayerVersion(player); + + GameProfile profile = new GameProfile(offlinePlayer.getUniqueId(), LegacyClient.ENTRY.get(rawSlot - 1) + ""); + EntityPlayer entity = new EntityPlayer(server, world, profile, manager); + + if (playerVersion != PlayerVersion.v1_7) { + profile.getProperties().removeAll("textures"); + profile.getProperties().put("textures", new Property("textures", Skin.DEFAULT.getValue(), Skin.DEFAULT.getSignature())); + } + entity.ping = 1; + + sendPacket(playerTablist.getPlayer(), PacketPlayOutPlayerInfoWrapper.newAddPacket(profile)); + + return new TabEntry(string, offlinePlayer, "", playerTablist, Skin.DEFAULT, column, slot, rawSlot, 0); + } + + @SuppressWarnings("unused") + @Override + public void updateFakeName(PlayerTablist playerTablist, TabEntry tabEntry, String text) { + if (tabEntry.getText().equals(text)) { + return; + } + + final Player player = playerTablist.getPlayer(); + final PlayerVersion playerVersion = PlayerVersionHandler.getPlayerVersion(player); + String[] newStrings = PlayerTablist.splitStrings(text, tabEntry.getRawSlot()); + + Team team = player.getScoreboard().getTeam(LegacyClient.NAMES.get(tabEntry.getRawSlot() - 1)); + team.setPrefix(ChatColor.translateAlternateColorCodes('&', newStrings[0])); + if (newStrings.length > 1) { + team.setSuffix(ChatColor.translateAlternateColorCodes('&', newStrings[1])); + } else { + team.setSuffix(""); + } + + tabEntry.setText(text); + } + + @Override + public void updateFakeLatency(PlayerTablist playerTablist, TabEntry tabEntry, Integer latency) { + if (tabEntry.getLatency() == latency) { + return; + } + + GameProfile profile = new GameProfile(tabEntry.getOfflinePlayer().getUniqueId(), LegacyClient.ENTRY.get(tabEntry.getRawSlot() - 1) + ""); + EntityPlayer entity = new EntityPlayer(server, world, profile, manager); + entity.ping = latency; + + sendPacket(playerTablist.getPlayer(), PacketPlayOutPlayerInfoWrapper.updateLatency(profile)); + tabEntry.setLatency(latency); + } + + @Override + public void updateFakeSkin(PlayerTablist playerTablist, TabEntry tabEntry, Skin skin) { + if (tabEntry.getSkin() == skin) { + return; + } + GameProfile profile = new GameProfile(tabEntry.getOfflinePlayer().getUniqueId(), LegacyClient.ENTRY.get(tabEntry.getRawSlot() - 1) + ""); + profile.getProperties().removeAll("textures"); + profile.getProperties().put("textures", new Property("textures", skin.getValue(), skin.getSignature())); + + sendPacket(playerTablist.getPlayer(), PacketPlayOutPlayerInfoWrapper.newRemovePacket(profile)); + sendPacket(playerTablist.getPlayer(), PacketPlayOutPlayerInfoWrapper.newAddPacket(profile)); + + + tabEntry.setSkin(skin); + } + + @Override + public void updateHeaderAndFooter(Player player, List header, List footer) { + IChatBaseComponent headerComponent = ChatSerializer.a("{text:\"" + StringEscapeUtils.escapeJava(this.getListFromString(CC.translate(header))) + "\"}"); + IChatBaseComponent footerComponent = ChatSerializer.a("{text:\"" + StringEscapeUtils.escapeJava(this.getListFromString(CC.translate(footer))) + "\"}"); + ProtocolInjector.PacketTabHeader packetTabHeader = new ProtocolInjector.PacketTabHeader(headerComponent, footerComponent); + sendPacket(player, packetTabHeader); + } + + public String getListFromString(List list) { + StringBuilder stringBuilder = new StringBuilder(); + for (int i = 0; i < list.size(); ++i) { + stringBuilder.append(list.get(i)); + if (i != list.size() - 1) { + stringBuilder.append('\n'); + } + } + return stringBuilder.toString(); + } + + @Override + public Skin getSkin(Player player) { + if (Skin.CACHE.containsKey(player.getUniqueId())) return Skin.CACHE.get(player.getUniqueId()); + + try { + CraftPlayer craftPlayer = (CraftPlayer) player; + EntityPlayer entityPlayer = craftPlayer.getHandle(); + + Property property = entityPlayer.getProfile().getProperties().get("textures").stream().findFirst().orElse(null); + + if (property != null) { + return Skin.CACHE.put(player.getUniqueId(), new Skin(property.getValue(), property.getSignature())); + } + } catch (Exception ignored) { + // ignored + } + + return Skin.STEVE; + } + + public static class PacketPlayOutPlayerInfoWrapper { + + private static MethodHandle PLAYER_SETTER; + private static MethodHandle USERNAME_SETTER; + private static MethodHandle ACTION_SETTER; + + static { + try { + MethodHandles.Lookup lookup = MethodHandles.lookup(); + + PLAYER_SETTER = lookup.unreflectSetter(Reflection.setAccessibleAndGet(PacketPlayOutPlayerInfo.class, "player")); + USERNAME_SETTER = lookup.unreflectSetter(Reflection.setAccessibleAndGet(PacketPlayOutPlayerInfo.class, "username")); + ACTION_SETTER = lookup.unreflectSetter(Reflection.setAccessibleAndGet(PacketPlayOutPlayerInfo.class, "action")); + } catch (Throwable t) { + t.printStackTrace(); + } + } + + public static PacketPlayOutPlayerInfo newAddPacket(GameProfile gameProfile) { + PacketPlayOutPlayerInfo packet = new PacketPlayOutPlayerInfo(); + + try { + PLAYER_SETTER.invokeExact(packet, gameProfile); + USERNAME_SETTER.invokeExact(packet, gameProfile.getName()); + ACTION_SETTER.invokeExact(packet, 0); + } catch (Throwable t) { + t.printStackTrace(); + } + + return packet; + } + + public static PacketPlayOutPlayerInfo newRemovePacket(GameProfile gameProfile) { + PacketPlayOutPlayerInfo packet = new PacketPlayOutPlayerInfo(); + + try { + PLAYER_SETTER.invokeExact(packet, gameProfile); + USERNAME_SETTER.invokeExact(packet, gameProfile.getName()); + ACTION_SETTER.invokeExact(packet, 4); + } catch (Throwable t) { + t.printStackTrace(); + } + + return packet; + } + + public static PacketPlayOutPlayerInfo updateLatency(GameProfile gameProfile) { + PacketPlayOutPlayerInfo packet = new PacketPlayOutPlayerInfo(); + + try { + PLAYER_SETTER.invokeExact(packet, gameProfile); + USERNAME_SETTER.invokeExact(packet, gameProfile.getName()); + ACTION_SETTER.invokeExact(packet, 2); + } catch (Throwable t) { + t.printStackTrace(); + } + + return packet; + } + + } + + private void sendPacket(Player player, Packet packet) { + getEntity(player).playerConnection.sendPacket(packet); + } + + private EntityPlayer getEntity(Player player) { + return ((CraftPlayer) player).getHandle(); + } + +} diff --git a/src/main/java/dev/aapy/tablist/impl/v1_8TabImpl.java b/src/main/java/dev/aapy/tablist/impl/v1_8TabImpl.java new file mode 100644 index 0000000..d1f8d49 --- /dev/null +++ b/src/main/java/dev/aapy/tablist/impl/v1_8TabImpl.java @@ -0,0 +1,347 @@ +package dev.aapy.tablist.impl; + +import com.mojang.authlib.GameProfile; +import com.mojang.authlib.properties.Property; +import dev.aapy.tablist.utils.CC; +import dev.aapy.tablist.utils.Reflection; +import dev.aapy.tablist.PlayerTablist; +import dev.aapy.tablist.TabColumn; +import dev.aapy.tablist.TabEntry; +import dev.aapy.tablist.TabNMS; +import dev.aapy.tablist.playerversion.PlayerVersion; +import dev.aapy.tablist.playerversion.PlayerVersionHandler; +import dev.aapy.tablist.skin.Skin; +import dev.aapy.tablist.utils.LegacyClient; +import net.minecraft.server.v1_8_R3.*; +import net.minecraft.server.v1_8_R3.PacketPlayOutPlayerInfo.EnumPlayerInfoAction; +import net.minecraft.server.v1_8_R3.WorldSettings.EnumGamemode; +import org.apache.commons.lang.StringEscapeUtils; +import org.bukkit.ChatColor; +import org.bukkit.Location; +import org.bukkit.OfflinePlayer; +import org.bukkit.craftbukkit.v1_8_R3.entity.CraftPlayer; +import org.bukkit.entity.Player; +import org.bukkit.scoreboard.Team; + +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.lang.reflect.Field; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.UUID; + + +public class v1_8TabImpl implements TabNMS { + + public v1_8TabImpl() { + } + + @Override + public TabEntry createFakePlayer(PlayerTablist playerTablist, String string, TabColumn column, Integer slot, Integer rawSlot) { + final OfflinePlayer offlinePlayer = new OfflinePlayer() { + private final UUID uuid = UUID.randomUUID(); + + @Override + public boolean isOnline() { + return true; + } + + @Override + public String getName() { + return string; + } + + @Override + public UUID getUniqueId() { + return uuid; + } + + @Override + public boolean isBanned() { + return false; + } + + @Override + public void setBanned(boolean b) { + + } + + @Override + public boolean isWhitelisted() { + return false; + } + + @Override + public void setWhitelisted(boolean b) { + + } + + @Override + public Player getPlayer() { + return null; + } + + @Override + public long getFirstPlayed() { + return 0; + } + + @Override + public long getLastPlayed() { + return 0; + } + + + @Override + public boolean hasPlayedBefore() { + return false; + } + + @Override + public Location getBedSpawnLocation() { + return null; + } + + @Override + public Map serialize() { + return null; + } + + @Override + public boolean isOp() { + return false; + } + + @Override + public void setOp(boolean b) { + + } + }; + final Player player = playerTablist.getPlayer(); + final PlayerVersion playerVersion = PlayerVersionHandler.getPlayerVersion(player); + + GameProfile profile = new GameProfile(offlinePlayer.getUniqueId(), (playerVersion != PlayerVersion.v1_7 ? string : LegacyClient.ENTRY.get(rawSlot - 1) + "")); + + if (playerVersion != PlayerVersion.v1_7) { + profile.getProperties().removeAll("textures"); + profile.getProperties().put("textures", new Property("textures", Skin.DEFAULT.getValue(), Skin.DEFAULT.getSignature())); + } + + sendPacket(playerTablist.getPlayer(), PacketPlayOutPlayerInfoWrapper.newAddPacket(profile, 1, player)); + + return new TabEntry(string, offlinePlayer, "", playerTablist, Skin.DEFAULT, column, slot, rawSlot, 0); + } + + @SuppressWarnings("unused") + @Override + public void updateFakeName(PlayerTablist playerTablist, TabEntry tabEntry, String text) { + if (tabEntry.getText().equals(text)) { + return; + } + + final Player player = playerTablist.getPlayer(); + final PlayerVersion playerVersion = PlayerVersionHandler.getPlayerVersion(player); + String[] newStrings = PlayerTablist.splitStrings(text, tabEntry.getRawSlot()); + if (playerVersion == PlayerVersion.v1_7) { + + Team team = player.getScoreboard().getTeam(LegacyClient.NAMES.get(tabEntry.getRawSlot() - 1)); + team.setPrefix(ChatColor.translateAlternateColorCodes('&', newStrings[0])); + if (newStrings.length > 1) { + team.setSuffix(ChatColor.translateAlternateColorCodes('&', newStrings[1])); + } else { + team.setSuffix(""); + } + } else { + + GameProfile gameProfile = new GameProfile(tabEntry.getOfflinePlayer().getUniqueId(), tabEntry.getId()); + + sendPacket(player, PacketPlayOutPlayerInfoWrapper.updateDisplayName(gameProfile, CC.translate(newStrings.length > 1 ? newStrings[0] + newStrings[1] : newStrings[0]), tabEntry.getLatency())); + + } + tabEntry.setText(text); + } + + @Override + public void updateFakeLatency(PlayerTablist playerTablist, TabEntry tabEntry, Integer latency) { + if (tabEntry.getLatency() == latency) { + return; + } + + GameProfile profile = new GameProfile(tabEntry.getOfflinePlayer().getUniqueId(), LegacyClient.ENTRY.get(tabEntry.getRawSlot() - 1) + ""); + + sendPacket(playerTablist.getPlayer(), PacketPlayOutPlayerInfoWrapper.updateLatency(profile, CC.translate(tabEntry.getText()), latency)); + + tabEntry.setLatency(latency); + } + + @Override + public void updateFakeSkin(PlayerTablist playerTablist, TabEntry tabEntry, Skin skin) { + if (tabEntry.getSkin() == skin) { + return; + } + GameProfile profile = new GameProfile(tabEntry.getOfflinePlayer().getUniqueId(), LegacyClient.ENTRY.get(tabEntry.getRawSlot() - 1) + ""); + profile.getProperties().removeAll("textures"); + profile.getProperties().put("textures", new Property("textures", skin.getValue(), skin.getSignature())); + + sendPacket(playerTablist.getPlayer(), PacketPlayOutPlayerInfoWrapper.newRemovePacket(profile, tabEntry.getLatency())); + sendPacket(playerTablist.getPlayer(), PacketPlayOutPlayerInfoWrapper.newAddPacket(profile, tabEntry.getLatency(), playerTablist.getPlayer())); + + tabEntry.setSkin(skin); + } + + @Override + public void updateHeaderAndFooter(Player player, List header, List footer) { + IChatBaseComponent headerComponent = IChatBaseComponent.ChatSerializer.a("{text:\"" + StringEscapeUtils.escapeJava(this.getListFromString(CC.translate(header))) + "\"}"); + IChatBaseComponent footerComponent = IChatBaseComponent.ChatSerializer.a("{text:\"" + StringEscapeUtils.escapeJava(this.getListFromString(CC.translate(footer))) + "\"}"); + PacketPlayOutPlayerListHeaderFooter packet = new PacketPlayOutPlayerListHeaderFooter(); + + try { + Field headerField = packet.getClass().getDeclaredField("a"); + headerField.setAccessible(true); + headerField.set(packet, headerComponent); + headerField.setAccessible(!headerField.isAccessible()); + + Field footerField = packet.getClass().getDeclaredField("b"); + footerField.setAccessible(true); + footerField.set(packet, footerComponent); + footerField.setAccessible(!footerField.isAccessible()); + } catch (Exception exception) { + exception.printStackTrace(); + } + sendPacket(player, packet); + } + + public String getListFromString(List list) { + StringBuilder stringBuilder = new StringBuilder(); + for (int i = 0; i < list.size(); ++i) { + stringBuilder.append(list.get(i)); + if (i != list.size() - 1) { + stringBuilder.append('\n'); + } + } + return stringBuilder.toString(); + } + + @Override + public Skin getSkin(Player player) { + if (Skin.CACHE.containsKey(player.getUniqueId())) return Skin.CACHE.get(player.getUniqueId()); + + try { + CraftPlayer craftPlayer = (CraftPlayer) player; + EntityPlayer entityPlayer = craftPlayer.getHandle(); + + Property property = entityPlayer.getProfile().getProperties().get("textures").stream().findFirst().orElse(null); + + if (property != null) { + return Skin.CACHE.put(player.getUniqueId(), new Skin(property.getValue(), property.getSignature())); + } + } catch (Exception ignored) { + // ignored + } + + return Skin.STEVE; + } + + private void sendPacket(Player player, Packet packet) { + getEntity(player).playerConnection.sendPacket(packet); + } + + private EntityPlayer getEntity(Player player) { + return ((CraftPlayer) player).getHandle(); + } + + + public static class PacketPlayOutPlayerInfoWrapper { + + private static MethodHandle PLAYER_INFO_SETTER; + private static MethodHandle ACTION_SETTER; + + static { + try { + MethodHandles.Lookup lookup = MethodHandles.lookup(); + + PLAYER_INFO_SETTER = lookup.unreflectSetter(Reflection.setAccessibleAndGet(PacketPlayOutPlayerInfo.class, "b")); + ACTION_SETTER = lookup.unreflectSetter(Reflection.setAccessibleAndGet(PacketPlayOutPlayerInfo.class, "a")); + } catch (Throwable t) { + t.printStackTrace(); + } + } + + public static PacketPlayOutPlayerInfo newAddPacket(com.mojang.authlib.GameProfile gameProfile, Integer ping, Player playerTab) { + PacketPlayOutPlayerInfo packet = new PacketPlayOutPlayerInfo(); + PlayerVersion playerVersion = PlayerVersionHandler.getPlayerVersion(playerTab); + + try { + PacketPlayOutPlayerInfo.PlayerInfoData infoData = new PacketPlayOutPlayerInfo.PlayerInfoData(gameProfile, ping, + EnumGamemode.NOT_SET, new ChatComponentText( + + + (playerVersion != PlayerVersion.v1_7 ? "" : gameProfile.getName()))); + + PLAYER_INFO_SETTER.invokeExact(packet, Collections.singletonList(infoData)); + ACTION_SETTER.invokeExact(packet, EnumPlayerInfoAction.ADD_PLAYER); + } catch (Throwable t) { + t.printStackTrace(); + } + + return packet; + } + + public static PacketPlayOutPlayerInfo newRemovePacket(GameProfile gameProfile, Integer ping) { + PacketPlayOutPlayerInfo packet = new PacketPlayOutPlayerInfo(); + + try { + PacketPlayOutPlayerInfo.PlayerInfoData infoData = new PacketPlayOutPlayerInfo.PlayerInfoData(gameProfile, ping, + EnumGamemode.NOT_SET, new ChatComponentText(gameProfile.getName())); + + PLAYER_INFO_SETTER.invokeExact(packet, Collections.singletonList(infoData)); + ACTION_SETTER.invokeExact(packet, EnumPlayerInfoAction.REMOVE_PLAYER); + } catch (Throwable t) { + t.printStackTrace(); + } + + return packet; + } + + public static PacketPlayOutPlayerInfo updateDisplayName(GameProfile profile, String displayName, Integer ping) { + PacketPlayOutPlayerInfo packet = new PacketPlayOutPlayerInfo(); + + try { + PacketPlayOutPlayerInfo.PlayerInfoData infoData = new PacketPlayOutPlayerInfo.PlayerInfoData(profile, ping, + EnumGamemode.NOT_SET, new ChatComponentText(displayName)); + + PLAYER_INFO_SETTER.invokeExact(packet, Collections.singletonList(infoData)); + ACTION_SETTER.invokeExact(packet, EnumPlayerInfoAction.UPDATE_DISPLAY_NAME); + } catch (Throwable t) { + t.printStackTrace(); + } + + return packet; + } + + + public static PacketPlayOutPlayerInfo updateLatency(GameProfile profile, String displayName, Integer ping) { + PacketPlayOutPlayerInfo packet = new PacketPlayOutPlayerInfo(); + + try { + PacketPlayOutPlayerInfo.PlayerInfoData infoData = new PacketPlayOutPlayerInfo.PlayerInfoData( + + profile, + ping, + EnumGamemode.NOT_SET, + new ChatComponentText(displayName)); + + PLAYER_INFO_SETTER.invokeExact(packet, Collections.singletonList(infoData)); + ACTION_SETTER.invokeExact(packet, EnumPlayerInfoAction.UPDATE_LATENCY); + } catch (Throwable t) { + t.printStackTrace(); + } + + return packet; + } + + } + + +} diff --git a/src/main/java/dev/aapy/tablist/playerversion/IPlayerVersion.java b/src/main/java/dev/aapy/tablist/playerversion/IPlayerVersion.java new file mode 100644 index 0000000..d676b36 --- /dev/null +++ b/src/main/java/dev/aapy/tablist/playerversion/IPlayerVersion.java @@ -0,0 +1,8 @@ +package dev.aapy.tablist.playerversion; + +import org.bukkit.entity.Player; + +public interface IPlayerVersion { + + PlayerVersion getPlayerVersion(Player player); +} diff --git a/src/main/java/dev/aapy/tablist/playerversion/PlayerVersion.java b/src/main/java/dev/aapy/tablist/playerversion/PlayerVersion.java new file mode 100644 index 0000000..baf4afe --- /dev/null +++ b/src/main/java/dev/aapy/tablist/playerversion/PlayerVersion.java @@ -0,0 +1,32 @@ +package dev.aapy.tablist.playerversion; + +import lombok.Getter; + +import java.util.Arrays; + +@Getter +public enum PlayerVersion { + + v1_7(4, 5), + v1_8(47), + v1_9(107, 108, 109, 110), + v1_10(210), + v1_11(315, 316), + v1_12(335, 338, 340), + v1_13(393, 401, 404); + + private final Integer[] rawVersion; + + PlayerVersion(Integer... rawVersionNumbers) { + this.rawVersion = rawVersionNumbers; + } + + public static PlayerVersion getVersionFromRaw(Integer input) { + for (PlayerVersion playerVersion : PlayerVersion.values()) { + if (Arrays.asList(playerVersion.rawVersion).contains(input)) { + return playerVersion; + } + } + return v1_8; + } +} diff --git a/src/main/java/dev/aapy/tablist/playerversion/PlayerVersionHandler.java b/src/main/java/dev/aapy/tablist/playerversion/PlayerVersionHandler.java new file mode 100644 index 0000000..2e9a265 --- /dev/null +++ b/src/main/java/dev/aapy/tablist/playerversion/PlayerVersionHandler.java @@ -0,0 +1,42 @@ +package dev.aapy.tablist.playerversion; + +import dev.aapy.tablist.playerversion.impl.PlayerVersion1_7Impl; +import dev.aapy.tablist.playerversion.impl.PlayerVersionProtocolLibImpl; +import dev.aapy.tablist.playerversion.impl.PlayerVersionViaVersionImpl; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.plugin.PluginManager; + +public class PlayerVersionHandler { + + public static IPlayerVersion version; + + public PlayerVersionHandler() { + /* Plugin Manager */ + PluginManager pluginManager = Bukkit.getServer().getPluginManager(); + + /* 1.7 Protocol */ + String serverVersion = Bukkit.getServer().getClass().getPackage().getName().split("\\.")[3]; + + if (serverVersion.equalsIgnoreCase("v1_7_R4")) { + version = new PlayerVersion1_7Impl(); + return; + } + + /* ViaVersion */ + if (pluginManager.getPlugin("ViaVersion") != null) { + version = new PlayerVersionViaVersionImpl(); + return; + } + + /* ProtocolLib */ + if (pluginManager.getPlugin("ProtocolLib") != null) { + version = new PlayerVersionProtocolLibImpl(); + return; + } + } + + public static PlayerVersion getPlayerVersion(Player player) { + return version.getPlayerVersion(player); + } +} diff --git a/src/main/java/dev/aapy/tablist/playerversion/impl/PlayerVersion1_7Impl.java b/src/main/java/dev/aapy/tablist/playerversion/impl/PlayerVersion1_7Impl.java new file mode 100644 index 0000000..c0a9b28 --- /dev/null +++ b/src/main/java/dev/aapy/tablist/playerversion/impl/PlayerVersion1_7Impl.java @@ -0,0 +1,16 @@ +package dev.aapy.tablist.playerversion.impl; + +import dev.aapy.tablist.playerversion.IPlayerVersion; +import dev.aapy.tablist.playerversion.PlayerVersion; +import org.bukkit.craftbukkit.v1_7_R4.entity.CraftPlayer; +import org.bukkit.entity.Player; + +public class PlayerVersion1_7Impl implements IPlayerVersion { + + @Override + public PlayerVersion getPlayerVersion(Player player) { + return PlayerVersion.getVersionFromRaw( + ((CraftPlayer) player).getHandle().playerConnection.networkManager.getVersion() + ); + } +} diff --git a/src/main/java/dev/aapy/tablist/playerversion/impl/PlayerVersionProtocolLibImpl.java b/src/main/java/dev/aapy/tablist/playerversion/impl/PlayerVersionProtocolLibImpl.java new file mode 100644 index 0000000..ec0613a --- /dev/null +++ b/src/main/java/dev/aapy/tablist/playerversion/impl/PlayerVersionProtocolLibImpl.java @@ -0,0 +1,15 @@ +package dev.aapy.tablist.playerversion.impl; + + + +import com.comphenix.protocol.ProtocolLibrary; +import dev.aapy.tablist.playerversion.IPlayerVersion; +import dev.aapy.tablist.playerversion.PlayerVersion; +import org.bukkit.entity.Player; + +public class PlayerVersionProtocolLibImpl implements IPlayerVersion { + @Override + public PlayerVersion getPlayerVersion(Player player) { + return PlayerVersion.getVersionFromRaw(ProtocolLibrary.getProtocolManager().getProtocolVersion(player)); + } +} diff --git a/src/main/java/dev/aapy/tablist/playerversion/impl/PlayerVersionViaVersionImpl.java b/src/main/java/dev/aapy/tablist/playerversion/impl/PlayerVersionViaVersionImpl.java new file mode 100644 index 0000000..653b356 --- /dev/null +++ b/src/main/java/dev/aapy/tablist/playerversion/impl/PlayerVersionViaVersionImpl.java @@ -0,0 +1,15 @@ +package dev.aapy.tablist.playerversion.impl; + + + +import dev.aapy.tablist.playerversion.IPlayerVersion; +import dev.aapy.tablist.playerversion.PlayerVersion; +import org.bukkit.entity.Player; +import us.myles.ViaVersion.api.Via; + +public class PlayerVersionViaVersionImpl implements IPlayerVersion { + @Override + public PlayerVersion getPlayerVersion(Player player) { + return PlayerVersion.getVersionFromRaw(Via.getAPI().getPlayerVersion(player)); + } +} diff --git a/src/main/java/dev/aapy/tablist/provider/TablistProvider.java b/src/main/java/dev/aapy/tablist/provider/TablistProvider.java new file mode 100644 index 0000000..e4980ee --- /dev/null +++ b/src/main/java/dev/aapy/tablist/provider/TablistProvider.java @@ -0,0 +1,311 @@ +package dev.aapy.tablist.provider; + +import dev.aapy.file.Tablist; +import me.activated.core.plugin.AquaCoreAPI; +import me.clip.placeholderapi.PlaceholderAPI; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.entity.Player; +import dev.aapy.tablist.TabColumn; +import dev.aapy.tablist.TabLayout; +import dev.aapy.tablist.TabProvider; +import dev.aapy.tablist.skin.Skin; +import dev.aapy.tablist.utils.CC; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; + + +public class TablistProvider implements TabProvider { + YamlConfiguration config; + + public TablistProvider() { + this.config = Tablist.getConfig(); + } + + @Override + public List getFooter(Player player) { + return CC.translate(Tablist.getConfig().getStringList("TAB.FOOTER")); + } + + + @Override + public List getHeader(Player player) { + return CC.translate(Tablist.getConfig().getStringList("TAB.HEADER")); + } + + @SuppressWarnings({"deprecation", "unchecked", "rawtypes"}) + public String factions(Player player, String path) { + path = path.replace("{players_online}", String.valueOf(Bukkit.getOnlinePlayers().size())); + if (path.contains("|")) { + path = path.replace("|", "\u2503"); + } + if (path.contains("{rank}")) { + path = path.replace("{rank}", AquaCoreAPI.INSTANCE.getPlayerRank(player.getUniqueId()).getColor().toString() + AquaCoreAPI.INSTANCE.getPlayerRank(player.getUniqueId()).getPrefix().toString()); + } + if (path.contains("{players_max_online}")) { + path = path.replace("{players_max_online}", String.valueOf(Bukkit.getMaxPlayers())); + } + if (path.contains("{ign}")) { + path = path.replace("{ign}",player.getName()); + } + return path; + } + + + private TabLayout getInfo(int slot, TabColumn place, Player p) { + TabLayout object = new TabLayout(); + + String text = ""; + switch (place) { + case LEFT: { + if (this.config.getString("TAB.LEFT." + slot + ".TEXT") == null || + this.config.getString("TAB.LEFT." + slot + ".TEXT") == " " || + this.config.getString("TAB.LEFT." + slot + ".TEXT") == "") { + text = " "; + break; + } + text = this.config.getString("TAB.LEFT." + slot + ".TEXT"); + break; + } + case RIGHT: { + if (this.config.getString("TAB.RIGHT." + slot + ".TEXT") == null || + this.config.getString("TAB.RIGHT." + slot + ".TEXT") == " " || + this.config.getString("TAB.RIGHT." + slot + ".TEXT") == "") { + text = " "; + break; + } + text = this.config.getString("TAB.RIGHT." + slot + ".TEXT"); + break; + } + case MIDDLE: { + if (this.config.getString("TAB.CENTER." + slot + ".TEXT") == null || + this.config.getString("TAB.CENTER." + slot + ".TEXT") == " " || + this.config.getString("TAB.CENTER." + slot + ".TEXT") == "") { + text = " "; + break; + } + text = this.config.getString("TAB.CENTER." + slot + ".TEXT"); + break; + } + case FAR_RIGHT: { + if (this.config.getString("TAB.FARRIGHT." + slot + ".TEXT") == null || + this.config.getString("TAB.FARRIGHT." + slot + ".TEXT") == " " || + this.config.getString("TAB.FARRIGHT." + slot + ".TEXT") == "") { + text = " "; + break; + } + text = this.config.getString("TAB.FARRIGHT." + slot + ".TEXT"); + break; + } + } + text = factions(p, text); + object.column(place); + if (Bukkit.getServer().getPluginManager().isPluginEnabled("PlaceholderAPI")) { + + object.text(PlaceholderAPI.setPlaceholders(p, text)); + } else { + object.text(text); + + } + object.slot(slot); + + String skin = ""; + switch (place) { + case LEFT: { + if (this.config.getString("TAB.LEFT." + slot + ".SKIN") == null || this.config.getString("TAB.LEFT." + slot + ".SKIN") == " " || this.config.getString("TAB.LEFT." + slot + ".SKIN") == "") { + skin = " "; + break; + } + skin = this.config.getString("TAB.LEFT." + slot + ".SKIN"); + break; + } + case RIGHT: { + if (this.config.getString("TAB.RIGHT" + slot + ".SKIN") == null || this.config.getString("TAB.RIGHT." + slot + ".SKIN") == " " || this.config.getString("TAB.RIGHT." + slot + ".SKIN") == "") { + skin = " "; + break; + } + skin = this.config.getString("TAB.RIGHT." + slot + ".SKIN"); + break; + } + case MIDDLE: { + if (this.config.getString("TAB.CENTER." + slot + ".SKIN") == null || this.config.getString("TAB.CENTER." + slot + ".SKIN") == " " || this.config.getString("TAB.CENTER." + slot + ".SKIN") == "") { + skin = " "; + break; + } + skin = this.config.getString("TAB.CENTER." + slot + ".SKIN"); + break; + } + case FAR_RIGHT: { + if (this.config.getString("TAB.FARRIGHT." + slot + ".SKIN") == null || this.config.getString("TAB.FARRIGHT." + slot + ".SKIN") == " " || this.config.getString("TAB.FARRIGHT." + slot + ".SKIN") == "") { + skin = " "; + break; + } + skin = this.config.getString("TAB.FARRIGHT." + slot + ".SKIN"); + break; + } + } + + object.skin(skins(p, skin)); + return object; + } + + + public Skin skins(Player player, String skinTab) { + Skin skinDefault = Skin.DEFAULT; + + + if (skinTab.contains("{player}")) { + skinDefault = Skin.getSkin(player); + } + if (skinTab.contains("{discord}")) { + skinDefault = Skin.DISCORD_SKIN; + } + if (skinTab.contains("{youtube}")) { + skinDefault = Skin.YOUTUBE_SKIN; + } + if (skinTab.contains("{twitter}")) { + skinDefault = Skin.TWITTER_SKIN; + + } + if (skinTab.contains("{facebook}")) { + skinDefault = Skin.FACEBOOK_SKIN; + + } + if (skinTab.contains("{store}")) { + skinDefault = Skin.STORE_SKIN; + } + + if (skinTab.contains("{green}")) { + skinDefault = Skin.getDot(ChatColor.GREEN); + } + if (skinTab.contains("{blue}")) { + skinDefault = Skin.getDot(ChatColor.BLUE); + } + if (skinTab.contains("{dark_blue}")) { + skinDefault = Skin.getDot(ChatColor.DARK_BLUE); + } + if (skinTab.contains("{dark_aqua}")) { + skinDefault = Skin.getDot(ChatColor.DARK_AQUA); + } + if (skinTab.contains("{dark_purple}")) { + skinDefault = Skin.getDot(ChatColor.DARK_PURPLE); + } + if (skinTab.contains("{light_purple}")) { + skinDefault = Skin.getDot(ChatColor.LIGHT_PURPLE); + } + if (skinTab.contains("{gray}")) { + skinDefault = Skin.getDot(ChatColor.GRAY); + } + if (skinTab.contains("{red}")) { + skinDefault = Skin.getDot(ChatColor.RED); + } + if (skinTab.contains("{yellow}")) { + skinDefault = Skin.getDot(ChatColor.YELLOW); + } + if (skinTab.contains("{dark_green}")) { + skinDefault = Skin.getDot(ChatColor.DARK_GREEN); + } + if (skinTab.contains("{dark_red}")) { + skinDefault = Skin.getDot(ChatColor.DARK_RED); + } + if (skinTab.contains("{gold}")) { + skinDefault = Skin.getDot(ChatColor.GOLD); + } + if (skinTab.contains("{aqua}")) { + skinDefault = Skin.getDot(ChatColor.AQUA); + } + if (skinTab.contains("{white}")) { + skinDefault = Skin.getDot(ChatColor.WHITE); + } + if (skinTab.contains("{dark_gray}")) { + skinDefault = Skin.getDot(ChatColor.DARK_GRAY); + } + if (skinTab.contains("{black}")) { + skinDefault = Skin.getDot(ChatColor.BLACK); + } + if (skinTab.contains("{warning}")) { + skinDefault = Skin.WARNING_SKIN; + } + if (skinTab.contains("{website}")) { + skinDefault = Skin.WEBSITE_SKIN; + } + if (skinTab.contains("{watch}")) { + skinDefault = Skin.QUEUE_SKIN; + } + if (skinTab.contains("{information}")) { + skinDefault = Skin.INFORMATION_SKIN; + } + if (skinTab.contains("{wood_shield}")) { + skinDefault = Skin.WOOD_SHIELD_SKIN; + } + if (skinTab.contains("{diamond_shield}")) { + skinDefault = Skin.DIAMOND_SHIELD_SKIN; + } + if (skinTab.contains("{bow}")) { + skinDefault = Skin.BOW_SKIN; + } + if (skinTab.contains("{potion}")) { + skinDefault = Skin.POTION_SKIN; + } + if (skinTab.contains("{telegram}")) { + skinDefault = Skin.TELEGRAM_SKIN; + } + if (skinTab.contains("{enderchest}")) { + skinDefault = Skin.ENDERCHEST_SKIN; + } + if (skinTab.contains("{coin}")) { + skinDefault = Skin.COIN_SKIN; + } + if (skinTab.contains("{heart}")) { + skinDefault = Skin.HEART_SKIN; + } + if (skinTab.contains("{earth}")) { + skinDefault = Skin.EARTH_SKIN; + } + if (skinTab.contains("{crown}")) { + skinDefault = Skin.CROWN_SKIN; + } + if (skinTab.contains("{castle}")) { + skinDefault = Skin.CASTLE_SKIN; + } + if (skinTab.contains("{ping}")) { + skinDefault = Skin.PING_SKIN; + } + if (skinTab.contains("{stats}")) { + skinDefault = Skin.STATS_SKIN; + } + if (skinTab.contains("{compass}")) { + skinDefault = Skin.COMPASS_SKIN; + } + + return skinDefault; + + } + + + @Override + public Set getProvider(Player player) { + Set toReturn = new HashSet<>(); + + + for (int i = 1; i < 21; ++i) { + toReturn.add(this.getInfo(i, TabColumn.LEFT, player)); + } + for (int i = 1; i < 21; ++i) { + toReturn.add(this.getInfo(i, TabColumn.MIDDLE, player)); + } + for (int i = 1; i < 21; ++i) { + toReturn.add(this.getInfo(i, TabColumn.RIGHT, player)); + } + for (int i = 1; i < 21; ++i) { + toReturn.add(this.getInfo(i, TabColumn.FAR_RIGHT, player)); + } + + return toReturn; + } + + +} \ No newline at end of file diff --git a/src/main/java/dev/aapy/tablist/skin/Skin.java b/src/main/java/dev/aapy/tablist/skin/Skin.java new file mode 100644 index 0000000..3b1c6c9 --- /dev/null +++ b/src/main/java/dev/aapy/tablist/skin/Skin.java @@ -0,0 +1,332 @@ +package dev.aapy.tablist.skin; + +import com.google.common.collect.Lists; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import dev.aapy.tablist.Tab; +import lombok.AllArgsConstructor; +import lombok.Getter; +import org.bukkit.ChatColor; +import org.bukkit.entity.Player; + +import java.io.IOException; +import java.io.InputStreamReader; +import java.net.URL; +import java.util.List; +import java.util.Map; +import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; + +@Getter +@AllArgsConstructor +public class Skin { + + private final String value; + private final String signature; + + public static final Map CACHE = new ConcurrentHashMap<>(); + + + @Override + public boolean equals(Object object) { + if (object == null) return false; + if (!object.getClass().equals(getClass())) return false; + + Skin skin = (Skin) object; + + return skin.getValue().equals(value) && skin.getSignature().equals(signature); + } + + + public static final Skin STEVE = new Skin( + "ewogICJ0aW1lc3RhbXAiIDogMTYxODI4Nzc3MDYxNSwKICAicHJvZmlsZUlkIiA6ICI4NjY3YmE3MWI4NWE0MDA0YWY1NDQ1N2E5NzM0ZWVkNyIsCiAgInByb2ZpbGVOYW1lIiA6ICJTdGV2ZSIsCiAgInNpZ25hdHVyZVJlcXVpcmVkIiA6IHRydWUsCiAgInRleHR1cmVzIiA6IHsKICAgICJTS0lOIiA6IHsKICAgICAgInVybCIgOiAiaHR0cDovL3RleHR1cmVzLm1pbmVjcmFmdC5uZXQvdGV4dHVyZS82MGE1YmQwMTZiM2M5YTFiOTI3MmU0OTI5ZTMwODI3YTY3YmU0ZWJiMjE5MDE3YWRiYmM0YTRkMjJlYmQ1YjEiCiAgICB9LAogICAgIkNBUEUiIDogewogICAgICAidXJsIiA6ICJodHRwOi8vdGV4dHVyZXMubWluZWNyYWZ0Lm5ldC90ZXh0dXJlLzk1M2NhYzhiNzc5ZmU0MTM4M2U2NzVlZTJiODYwNzFhNzE2NThmMjE4MGY1NmZiY2U4YWEzMTVlYTcwZTJlZDYiCiAgICB9CiAgfQp9", + "dnRZKI5Y443vH8PJASARp6D1RKayS5aAxEg6xkPX0wiIVo94YWiCu86/2NrYeh/Ltm76wHN9lTi/gBfhGY/De70SINNZEgTYAso9G3NsoBmAzQawsMdK5e4IRHvx5jun5sPqGS63Kb4Kuue8VNzsWz1eVOJus6GlN36GFwvO32qrXhhJaEho21MIYa9ySQQua38I3/Du5wfKiC5JerVjr7LP1GXEQvz3OrCP0u0dNs56JlqMjmTIcLmStx4EKJaHks5rfUKZON79TpjyJQkmw2rWOL2357ROpp3dBtH12Tie3MHchwYd7JEtkKx7JVq7kgVjF4yCBJ2ugBH8+Nc/GQij03sK4dASj3S+/o7zdBvWRIOnqNa7KEpP2s3l846NRwSC5YlKBK4hlccmGnlpmBzHlPl4b1vA3jZNG1HBNQ6VHX/LIJRUfvWnEXZVU0b+usTTdTdx5HB1ZYfN4Uekk/ilE5R/UNQ7A1q9EJ/WnbfA/SeZHda4k0he9PJDp52mcHMB0Q+fb1dEgFnxkF1OVHtJsHKi2zplpDtTPejy98d5qvBwVa9Ss2ygc1eoBG6QCcrf7ESTWgNrNPJLdEkahQCDVad6B8UpMq8LLREf2csMQt89XoAgS6n9OZTSLbzUxttvIq+Dkzo9Ae9iz3JlmEIGcBKoAE+9UUTl52L+E8o=" + ); + + public static final Skin DEFAULT = new Skin( + "eyJ0aW1lc3RhbXAiOjE0MTEyNjg3OTI3NjUsInByb2ZpbGVJZCI6IjNmYmVjN2RkMGE1ZjQwYmY5ZDExODg1YTU0NTA3MTEyIiwicHJvZmlsZU5hbWUiOiJsYXN0X3VzZXJuYW1lIiwidGV4dHVyZXMiOnsiU0tJTiI6eyJ1cmwiOiJodHRwOi8vdGV4dHVyZXMubWluZWNyYWZ0Lm5ldC90ZXh0dXJlLzg0N2I1Mjc5OTg0NjUxNTRhZDZjMjM4YTFlM2MyZGQzZTMyOTY1MzUyZTNhNjRmMzZlMTZhOTQwNWFiOCJ9fX0=", + "u8sG8tlbmiekrfAdQjy4nXIcCfNdnUZzXSx9BE1X5K27NiUvE1dDNIeBBSPdZzQG1kHGijuokuHPdNi/KXHZkQM7OJ4aCu5JiUoOY28uz3wZhW4D+KG3dH4ei5ww2KwvjcqVL7LFKfr/ONU5Hvi7MIIty1eKpoGDYpWj3WjnbN4ye5Zo88I2ZEkP1wBw2eDDN4P3YEDYTumQndcbXFPuRRTntoGdZq3N5EBKfDZxlw4L3pgkcSLU5rWkd5UH4ZUOHAP/VaJ04mpFLsFXzzdU4xNZ5fthCwxwVBNLtHRWO26k/qcVBzvEXtKGFJmxfLGCzXScET/OjUBak/JEkkRG2m+kpmBMgFRNtjyZgQ1w08U6HHnLTiAiio3JswPlW5v56pGWRHQT5XWSkfnrXDalxtSmPnB5LmacpIImKgL8V9wLnWvBzI7SHjlyQbbgd+kUOkLlu7+717ySDEJwsFJekfuR6N/rpcYgNZYrxDwe4w57uDPlwNL6cJPfNUHV7WEbIU1pMgxsxaXe8WSvV87qLsR7H06xocl2C0JFfe2jZR4Zh3k9xzEnfCeFKBgGb4lrOWBu1eDWYgtKV67M2Y+B3W5pjuAjwAxn0waODtEn/3jKPbc/sxbPvljUCw65X+ok0UUN1eOwXV5l2EGzn05t3Yhwq19/GxARg63ISGE8CKw=" + ); + + private static final List DOT_SKINS = Lists.newArrayList(); + + public static final Skin DISCORD_SKIN; + public static final Skin FACEBOOK_SKIN; + public static final Skin TWITTER_SKIN; + public static final Skin YOUTUBE_SKIN; + + public static final Skin PLANET_SKIN; + public static final Skin WARNING_SKIN; + + + public static final Skin STORE_SKIN; + + public static final Skin ONLINE_SKIN; + public static final Skin OFFLINE_SKIN; + public static final Skin QUEUE_SKIN; + public static final Skin WEBSITE_SKIN; + + + public static final Skin INFORMATION_SKIN; + public static final Skin WOOD_SHIELD_SKIN; + public static final Skin DIAMOND_SHIELD_SKIN; + public static final Skin BOW_SKIN; + public static final Skin POTION_SKIN; + public static final Skin TELEGRAM_SKIN; + public static final Skin ENDERCHEST_SKIN; + public static final Skin COIN_SKIN; + public static final Skin HEART_SKIN; + + public static final Skin EARTH_SKIN = new Skin( + "ewogICJ0aW1lc3RhbXAiIDogMTYyODE3ODczOTQzNywKICAicHJvZmlsZUlkIiA6ICI5MzI0N2IzMzllMTQ0MDBkYjk5Y2ViM2Y0NzA4ZTBhNiIsCiAgInByb2ZpbGVOYW1lIiA6ICJBemFyb3dfIiwKICAic2lnbmF0dXJlUmVxdWlyZWQiIDogdHJ1ZSwKICAidGV4dHVyZXMiIDogewogICAgIlNLSU4iIDogewogICAgICAidXJsIiA6ICJodHRwOi8vdGV4dHVyZXMubWluZWNyYWZ0Lm5ldC90ZXh0dXJlL2EzMWI3ZDdlNjM0ZjBhZjA1MTFmYzg0NzYxMGE4NjVlYzFjODQwMjM0MTAwMDg5M2FiNjM5NzlmYzhlODVlMzUiLAogICAgICAibWV0YWRhdGEiIDogewogICAgICAgICJtb2RlbCIgOiAic2xpbSIKICAgICAgfQogICAgfQogIH0KfQ==", + "lKjhX6fDX0JxC++G/xo9k4q7psvLx7HAadzdQ9iasfYBw3jCzqVgXaHkhlNyN+iluFHevPqJ0nLobatuATyjexKASOE5wRQmL9WgdJnYEaQnb8+abE2sei2eS6tHGVkzYYbFmv4GmzcpA/CIk2HeSguVhZ4+zxQcnJYVFQqi2qyUo5ZMwLQ9ZiNaVy29LHYcIQp5yGBGFcoZIj0StLhrPOtN8GkBSLaTah2wUMtyAFGa5GJivd0lYh+7MPMZX6MIoZgtmCQC1ZLtiJmyByQv8mAfTAdcNKVpXoK0/F+RjkHIQkQ7hRfIV+g41l7H4SmfW53UMpxv7NXE4gv6Fu3OzSGE6Wmg2BkWbOTj4oIqsnfRPEFozesNwqfgQidP0ngqnRHIG5eX8iI6cXwFNFX7RFTXtIpJ8JhWOLyFAAFcdW46skCIKECm7eH0pEgJl7Q/22hnAz8rnoSh+irxbLQtTeyekUoPSpAPFPtp96Ud401Q7F30gYgpcrZztQ+hxbEnapLFv9l+4fda4USub4+9MlYaWpLWv+a+6EexLYOu163GCdEbkLdQsj2qPk87pRicw3v5pBq7ZnLN3nBGFU5WBsrfOggYfxnrlUDhyK3A7nZcTwc4qAZjS3ptWrk+HydQBNn09Zf8E+kdHArqy8ov0CMcwNFt3r0SOwvnvuxC7V8=" + ); + public static final Skin CROWN_SKIN = + new Skin("ewogICJ0aW1lc3RhbXAiIDogMTYyODE3ODc1NDAyMSwKICAicHJvZmlsZUlkIiA6ICIyM2YxYTU5ZjQ2OWI0M2RkYmRiNTM3YmZlYzEwNDcxZiIsCiAgInByb2ZpbGVOYW1lIiA6ICIyODA3IiwKICAic2lnbmF0dXJlUmVxdWlyZWQiIDogdHJ1ZSwKICAidGV4dHVyZXMiIDogewogICAgIlNLSU4iIDogewogICAgICAidXJsIiA6ICJodHRwOi8vdGV4dHVyZXMubWluZWNyYWZ0Lm5ldC90ZXh0dXJlLzRmOWM3M2EzMTNlNjkxZjY3YzdjZmFkMjRlYTlmY2U4OGFkOGZkNGNkYzE4YjZiODViNTc0M2I0Yzg1ZTVhNmQiLAogICAgICAibWV0YWRhdGEiIDogewogICAgICAgICJtb2RlbCIgOiAic2xpbSIKICAgICAgfQogICAgfQogIH0KfQ==", + "XPrRIarTKPwHpF+HhkrAlVzH3hnzCDJlMZXJFKf7jo9YkYJyTc5D1UQSQlZw6k2k5ZdbEXUp1xonPiYMr9auf88uURz2UvdrDtXkKZ2DD5u9t5f0ktWEA06HijfG7iHERum89xA1RLr0zmMwNcrgCHtteebfZJM3B5JkRYRDjgF3i3D6JYuC79JsQVDAro6aPHzVbxTog3FW7UaQ5FC2cSr88rrE692/dHyJfqcj2Kqy3lIFBaWhUa3YY0B4dCUowVsvdDhMH/Y7kt5yLkc+hCDafZ0+/OptQ+/YppcZDrMC+L7JQBDIy5KrICKKMdHPM2CmNUMK8qUscLKqeIANxZ12WR4526leSD+2cxQKQ7vXxbSy4ujWxV3seUJIwk0ln/RbMvfC2CwmsVW9vUQbqM4Ci/+oyL4qqBtEqPqtfC6OKaxJXkB+zqmRlZpmSsPgXKTpJuBY6ixFigRNpTL4DiT7byZTZZUdDvWXhOAr5NAoSBr3thQ9t8j5saF02clBeA2dmatsty56F/bmgqKg4mpi8I/ICkZ38FGMInq7AUXtQMFgDWpCVlJ3O38KDaZcO9NCjsfzCp8NcfcZ2vSkXxgdVDLHdSm7dgBKyIuofmgztgWzLRq+/LdMMjZcsi89ZUdA2826HxxC1LgZvDRt6o8sQHhegryCKJnKinYMXUA="); + public static final Skin PING_SKIN = + new Skin("ewogICJ0aW1lc3RhbXAiIDogMTYyODE3ODczMjg1MiwKICAicHJvZmlsZUlkIiA6ICI0ZDEzZWUyZjViOWI0N2I2OGU2NzhhMjAxN2VmZTc1MyIsCiAgInByb2ZpbGVOYW1lIiA6ICJCcmF5ZGVyZWsiLAogICJzaWduYXR1cmVSZXF1aXJlZCIgOiB0cnVlLAogICJ0ZXh0dXJlcyIgOiB7CiAgICAiU0tJTiIgOiB7CiAgICAgICJ1cmwiIDogImh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvZWRjMzEwYzQ3Y2FjOGM3MGRhYmQ3MTVhZDc1MzRlNmUxOTc4ZDBmMWQ5YWY0OGNhZWQzYzBjZjM5ZmQ5NmRhYSIKICAgIH0KICB9Cn0=", + "AKVgDDVqCv13V5+/2HNs7LlHMfB5kReaweJU2DiUQo4B4vctCqk1cJomkE1N1F2FAWlIvhkc58/zXqxNLhTXFMdzrhfle6BfKyocNeXz7BYwXIHD3RkD5187VHQb6y3rbBw9G4qdTLmEZPc/0/f2HJH46qV03YWxGXgFSjpQR48u00ZnLJWXumcGXYTzLUBFN2rJfPAB4j+chNs/MWOk/Bs0fo+OmNW2TRHt0KT2+Bdyg6a9xLPFKxtzzDZaWsW1ayuM0L95MOUCvS9O56oVVZQ+TUjVhqindugXqy9dQr9RAXbIFW/rthPgvdlujpSyc7oa4MqMuG84CHHvidOoKmKf14kv6kSjnjdfWAMQ1YM+vTvaBWvIuUrNYraW4zqLeVi2apNV+oFCI+xOn6P+GQzQkiDLI5oCvc5FcrM6L159ctPC5jRtwTH45G66MiJja/WK1u38Q8FseuSfDmutkGdJs7sim0AOlkpd9df7hZxNFnnlW4O3DI4nuwAMGkwfEh4T/U4nXitza2Rgk9EHH0hcFG5W2cCVUt4wImHbMRtOKlMWZ2+ZZWctu1AmttDCkFoEUyeEQSMkIPiWFTPBhgtDDRbYop3macH9l3Y9Nhq6/I5uphfbxve6ArQBPpW+mENiUtVuJaQDJTydUZ3xgR4bwrqneHd6iTNj6hTTdFE="); + + public static final Skin STATS_SKIN = + new Skin("ewogICJ0aW1lc3RhbXAiIDogMTYyODE3ODY3Njc3NSwKICAicHJvZmlsZUlkIiA6ICI1N2IzZGZiNWY4YTY0OWUyOGI1NDRlNGZmYzYzMjU2ZiIsCiAgInByb2ZpbGVOYW1lIiA6ICJYaWthcm8iLAogICJzaWduYXR1cmVSZXF1aXJlZCIgOiB0cnVlLAogICJ0ZXh0dXJlcyIgOiB7CiAgICAiU0tJTiIgOiB7CiAgICAgICJ1cmwiIDogImh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvMzJkYmFkNzIzOGE5YjM2NWM2OWYxOTk5MWJhZmRmNzEwNjU0ZjMyM2Y0MWE0NGU5ZjEwMjZjYzIwNTkyNzExNSIsCiAgICAgICJtZXRhZGF0YSIgOiB7CiAgICAgICAgIm1vZGVsIiA6ICJzbGltIgogICAgICB9CiAgICB9CiAgfQp9", + "GFnXdHoFH3vUgvizZ5N7wxoOsSNvvPgsuUlWr/eIpGs6EQZotqPpUjZBlZmbwYQrNj076BGeWx4nrxhFxR4A54NZeXB08J661zE8ddXliwg4aTgsxEvPgOqXkAb7rKTR2oe5FE0lC1IUI7ZXN+6C3/nxJ7fmMULJp4sOeHfzuYZa5xYFfpd3wy6knKs6SJf6BobaN8/ooqTAUP+yDvdbeA5uuk2Ljc0Pi4P7mWPABLFLfttvzhcjFy+3i8y1TbjKVnP8ILC2h3liXZUGIBHH3OGmWjNEVgg6znPVkqfKNarEv/CF9H9Sd3S9SCL2v2fKmd1TP3Qd8tT5CbxeMFDlOxCUgfkj0b5mgvkAwVYjpXk8RR2y8643sQN04p9ctNK1bTZdAqMyIkJbSAh5JUNgX7AZxLq7WJoM+85vXiZRpKHCXNY1psu2Z1NU0YahB2e0wQDka+CprmgvdRYJcupb2fwpZN4TmyQWf+/WrGPBAgQbOqTYqe63RVrwDhHd6vSn0mIvjbmP/6vi179Ww3ZgkfPXErwqYAy8ARcjuLoB30QbbLfMC0KC3LmW9EjBgQUotGNrysi4r7BC3gOjGdNJRB1QBAcyvg9PaDtiFuyVCFbAhfS1mDy1I/1S1sKqf6KoYmzPAU1YHIFHajOQ+DIWkFe3+SGQqZ4qQoceJTbpcyU="); + public static final Skin CASTLE_SKIN = + new Skin("ewogICJ0aW1lc3RhbXAiIDogMTYyODE3ODc2NDgxNywKICAicHJvZmlsZUlkIiA6ICI4YWFlYTdlYjViOWM0ZWEwODUxNWU3MDhhZGIxODBkNyIsCiAgInByb2ZpbGVOYW1lIiA6ICJNYVBhODA3MTEiLAogICJzaWduYXR1cmVSZXF1aXJlZCIgOiB0cnVlLAogICJ0ZXh0dXJlcyIgOiB7CiAgICAiU0tJTiIgOiB7CiAgICAgICJ1cmwiIDogImh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvY2MyMDI1YTdiYTJhYjZhODYxOTk5N2VhMjMzMTBmNTk4NGExZjRjNThkZjllOTYxNjVlZjFmNDliYmQ3ZTllMCIKICAgIH0KICB9Cn0=", + "VXJnpMLuXnV6eKHODxb86GS/iTPzuV4CIpDK1arbuiaOdySIUYtm9j9vzvKMHJRyrgarNt8TkGXVJo5for7kfzc990CZXou9erTv1YhOWvm6FRjW8nusV4gmLKla0sI6GU1y85LizCP6An51QUNS73c4OsfFY5Ng9OhYjYKJ+3DiVHs/hg4UOux/BedjbUdJIPpFBJIMRisURi4eCcH+1zahC8GBK0s5O3KUsGd/jdszDVYeJ6B9jqd9RT+Ww3b/s3eoy+G8NArp6XdFKFV/Hp3TXvaCw5IENnniGgRMLZ/w9MGDnO0/81dTO8BUqVymNLEj8fKPOfmahEtvQcIXt+fNQLIaSgFuTLpc+NEfX6XtqVNAz2huKpg46ym+k/qjxev/7i4CGPGCf9rMgc4dUYfJm/h5Nwybt8ciE3RmyuGqYCTY7nEQFKEoTBlW9UUijqZO1F17Dhe7hmxjpd6i0OITjCdiWEE/S5v7e0Mq3BmsQjs07TA9aOp/dLRUIOAYivfOIXKRRN1OFc1noO00sVro+kt3RSLWKToD8IYOgovsOcHgcizrnhsYGWfbJo08z74X5I2IKYowDjpV3SEI5GSiX1HT13fxpSybXGSZ12Vmd11wVgJ/OCjEg5jUSuLzWDpK6kLM+QZgff/8hbMOMoNfDeqcBcvXTr8HBgZQClk="); + + public static final Skin COMPASS_SKIN = + new Skin("ewogICJ0aW1lc3RhbXAiIDogMTYyODE3ODk2MDc0OCwKICAicHJvZmlsZUlkIiA6ICJhMjk1ODZmYmU1ZDk0Nzk2OWZjOGQ4ZGE0NzlhNDNlZSIsCiAgInByb2ZpbGVOYW1lIiA6ICJWaWVydGVsdG9hc3RpaWUiLAogICJzaWduYXR1cmVSZXF1aXJlZCIgOiB0cnVlLAogICJ0ZXh0dXJlcyIgOiB7CiAgICAiU0tJTiIgOiB7CiAgICAgICJ1cmwiIDogImh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvNjA1OTcwNGQ2NzQ3ZTkzOWFlN2YxYWNkZWRlODU3Yjk3OGM2NGMxNzJjOWRiZWY1MjVjNWNjNmQyMzE0NjY2NSIsCiAgICAgICJtZXRhZGF0YSIgOiB7CiAgICAgICAgIm1vZGVsIiA6ICJzbGltIgogICAgICB9CiAgICB9CiAgfQp9", + "OCVftL19cjD2kLoJgExHWLm8k7xgl8WEKQ57pqN3iOuR38HJ6HDKB34RKnezKBI+tyfoXCnxZugfKON2oPOsFER65jVT2rUqVjnqRb4cQjYWpzTmasz1reZnqWnlseFAquCbdIkV/c3Zo4x2I4lwOdveCE/IAFz/dxxc1zW90cfE16F4/qmKu7xd9FxuoGJeJkHLV/4NakI0o8Va3FlGo4K3foUsdJNDP75NRnzl/wOLS0tdf1uyZFYc2wJLBgULL9RLnMjFcukRG1FNDL/IOfMMddoep/DCEnBcoO2CIW2StTZjzVqrdkC53pNGqV/v7Qrmg0uL7qVSm0h0TnIFAdvvaRV/dQ6H9uB2ftUSZajO1dxhK0z8+EuJQDPzRWQgwVgN5iHx9cGRV5urbZvt+InbDOVHo/JKkUiDo/AefRGc8PglCIe8obk2+Z0SGL2xw0wny16LCKXcbMaF8As/BlckNHiexxcAZFSQmipVmTH0bXEoPYkf57ILRIFx3nf7z2D8fzv/2qCOuVPMN38O8e4kra1aCZhJx9dN6li7Ar1Tn5/zJ+lF9XNWFZnFyUdrTveeaWAwfNkiZ8W7OwRbvVoz2REW9xtrFietjzx8CIGPj4FJcYbaNkTmhT3yBxfBS6S2KgCRIas8R1tUOXG4LxEk3E0FKUSoPJg6wbdTnMM="); + + + static { + WOOD_SHIELD_SKIN = new Skin( + "ewogICJ0aW1lc3RhbXAiIDogMTYxNzQyNjkyODg0OCwKICAicHJvZmlsZUlkIiA6ICJiYzRlZGZiNWYzNmM0OGE3YWM5ZjFhMzlkYzIzZjRmOCIsCiAgInByb2ZpbGVOYW1lIiA6ICI4YWNhNjgwYjIyNDYxMzQwIiwKICAic2lnbmF0dXJlUmVxdWlyZWQiIDogdHJ1ZSwKICAidGV4dHVyZXMiIDogewogICAgIlNLSU4iIDogewogICAgICAidXJsIiA6ICJodHRwOi8vdGV4dHVyZXMubWluZWNyYWZ0Lm5ldC90ZXh0dXJlLzhkMTc0ZjU5YmNhYTYxNDlhZTVlYzRmNDE0MWM0ZTU3M2U5M2E0MzI3YzI2NDI3OWJlM2U4N2VhNzUyMWY0NjQiLAogICAgICAibWV0YWRhdGEiIDogewogICAgICAgICJtb2RlbCIgOiAic2xpbSIKICAgICAgfQogICAgfQogIH0KfQ==", + "XcPZhO0+VxdN+Vf/SRJ9/TXkS7WxNe+sL2eTLODZ+Q8z94ej7bgoSnwszjX0RLDLSiA16ueOHeSZLnJp189Yh9ja7nbuAkhQcU7Gq5IbdSiVioWp8P81H3byjXrGfr8k8d+SUB3HMQfr2ARPQG39AzOdaNymSPFlAMqvG0txMRyZQJISXHcehcPMx2Woz75Ne5QTo352jqF3GOEIgce1yTRhWs6n5l5+t8zqlmwEk0pvMoRNuKRdDd8/7iccYalqcKsr0yE7ytvTbgpmnuZhcRqqDg2BQMdT1okhk/5pvbSAvqhP5NDVAqrmOgF5YHB5I/H5EVd4xIocYzKZLBOwOTYKOHpeSL+c/cCEkiPq/omcLvFDLFX5Cl5P2CbNvYS/ELuKMa9qvIDSVo+bbQkOLaU7az2bRbaYDX4SkIboiBFjJCxlyr2aa3eFf1yCWt5JlQsx02ZT2xHBbdZfkYiGEJ4HWA6u27vxdKNRyySmMPnQ8hK9KT+b535NUiGaI7VO0Ni4vOgst4PXZYSAow6eEtfNQDw2nJqgjJgRvIGfQZhIGh2VDOcqewOVyfshCywRSuRI9l3XL1N6iJsYqj2CrpQVOatawV8YHdhRJ7f5RfE1FRET2g+PbXtTEI3Tu5p+//eKWYUpiRR0eU6LRz84/Tfk72/qxbGJFDQrnGr9c0w=" + ); + + + DIAMOND_SHIELD_SKIN = new Skin( + "ewogICJ0aW1lc3RhbXAiIDogMTU5ODk5MDYxOTg4MSwKICAicHJvZmlsZUlkIiA6ICI5MThhMDI5NTU5ZGQ0Y2U2YjE2ZjdhNWQ1M2VmYjQxMiIsCiAgInByb2ZpbGVOYW1lIiA6ICJCZWV2ZWxvcGVyIiwKICAic2lnbmF0dXJlUmVxdWlyZWQiIDogdHJ1ZSwKICAidGV4dHVyZXMiIDogewogICAgIlNLSU4iIDogewogICAgICAidXJsIiA6ICJodHRwOi8vdGV4dHVyZXMubWluZWNyYWZ0Lm5ldC90ZXh0dXJlLzI1MjU1OWYyYmNlYWQ5ODNmNGI2NTYxYzJiNWYyYjU4OGYwZDYxMTZkNDQ2NjZjZWZmMTIwMjA3OWQyN2NhNzQiCiAgICB9CiAgfQp9", + "Tig86czlFqclLJAPUny5gwL8SHENX+St6KTD68YKiAzQJo1Z/5NToq/8XV/2xSnJjdiuB02d6wnACxYg48Sfo5+hcEpLA4YqmNkDriNQuB1Im3I4WCTS6ItkHyqBzQDQEDcA45o0/eWpalht9X7KRYamOGuw0ajltB/bZrWOX7hjOg1qaXpURsO4AlybUjtX+bwm8cb09JEQ5tzZM/B/tMjkg6BVSvgxG76F7dFH4zYV9HLZilk/Mt7B1pPJxN2Wfvod4ucin1pcohepxqRRSXH4g3d4r0sPrgb2O/iT93dh0gE83G7YIUxIp/vwRpDLid40gYGphYvzvhmld8y3vMsKqRgHeb/nmLhDuEnaetWbNGT+yYKcXtKEyYbzCwb+Ecq4+BdRGI0ZdB7084iZVfQONmoTkp8hXu/VRtomyaQRWOwTdCYGgz1vA7iM+NHp/Hg+BrN1WQs6+6uy7Rjwo3Db92NSYW5bkiHNp2II22qdnrZ/oekdCc4EkYasMbLhIzZ4iz17KTXjgV00BgeJ8XvkcuX49tB3Hr7sgmsy1K7zp0zByEb64Q3qbGVB1epmbqZYeJNsdq95ZJ1VGqqPVdVCpTM3XAnjBtc1mgdXInQI8fWhrtRXRDpyzZ4hA8XTCeofXBT9/MjybvFAqyOiRBdIskoO9CsiuZUwsDxaezg=" + ); + + BOW_SKIN = new Skin( + "ewogICJ0aW1lc3RhbXAiIDogMTYxNzQyNzE5ODc4NCwKICAicHJvZmlsZUlkIiA6ICI5ZDEzZjcyMTcxM2E0N2U0OTAwZTMyZGVkNjBjNDY3MyIsCiAgInByb2ZpbGVOYW1lIiA6ICJUYWxvZGFvIiwKICAic2lnbmF0dXJlUmVxdWlyZWQiIDogdHJ1ZSwKICAidGV4dHVyZXMiIDogewogICAgIlNLSU4iIDogewogICAgICAidXJsIiA6ICJodHRwOi8vdGV4dHVyZXMubWluZWNyYWZ0Lm5ldC90ZXh0dXJlLzJhOWZhMzZhZjhkNmI2MDg1MDlkMjY4ZTJkYzE2MDY0ZDcyOGY4MjQwYWRjNTRjOWQ3ZDUxYTE5MTc3MDMyYTYiCiAgICB9CiAgfQp9", + "CQB3pJMuzjE7G8yaxNl+ks8weqHhD0JxGUMqYHCf6AUQM7rAEwxCKvm2sbelnKjCof4BXCHL2GKzG5AEAmz1kj+ZD9egDb4H1l3TCXGiA6vL3Ey2LpS+g0x2S0MkFVTONGAnhP/zt0gjC3PG9QH/W/7k64HyxnyBOPRVn9KLgVVnVkAMYWiPwp7XzuEAaWBEC1t9/0YB0RjxpOnV8n7lL121StH5czSU2fGWcSv4Cb/jbEhtCZW+pyDzttGPYUa8/RHqD+cM60Y23sYU5jZwyQDx7onPWrlTHpz3iwClAR7UWOtdlUWDGwsR6CtxsEvmPfmN2r2WKnR+GuYcj0riGic0nTXuEz5MB3gkFfmPARQfcOPkG+wV0+2KyTxtU4HZJMBPvbX9zEigKhZnzwvWsWpTHdbxpNc69H+TURowuNvDRj21h/exTlOykPglzCF/Bh5lTa3Kg6tuII8n3z7ibSY6e8kKzV+hmlxvq0hhMw0/CHsp0iBrh4IFYCvU+LTA+8erKGQlrUs+N843MC09toAQr08gJL2xHEYGWq0tKFPVKsC4r56CZD4fMqcSUTbEgiEC7kunl4c5W6z8BuhfkSu1q5IE2CQn2eXUt404IE80jBmqSl7OQhdpNNQbiGYCssR45fL7xTin92CXEMkCiuL3qAJdDWZN+uaeZdaSUD0=" + ); + + + POTION_SKIN = new Skin( + "ewogICJ0aW1lc3RhbXAiIDogMTYxNzQyNzU4MDcyOCwKICAicHJvZmlsZUlkIiA6ICJjZGM5MzQ0NDAzODM0ZDdkYmRmOWUyMmVjZmM5MzBiZiIsCiAgInByb2ZpbGVOYW1lIiA6ICJSYXdMb2JzdGVycyIsCiAgInNpZ25hdHVyZVJlcXVpcmVkIiA6IHRydWUsCiAgInRleHR1cmVzIiA6IHsKICAgICJTS0lOIiA6IHsKICAgICAgInVybCIgOiAiaHR0cDovL3RleHR1cmVzLm1pbmVjcmFmdC5uZXQvdGV4dHVyZS8xN2UzZGI2NDAxNGE0Nzg4NjcwZTQ5Y2E3YmUzZGE0MWZmM2ZiYmFmMWM1Mzk1ODRjNjM1MzU5YTVjYjYwYWFiIiwKICAgICAgIm1ldGFkYXRhIiA6IHsKICAgICAgICAibW9kZWwiIDogInNsaW0iCiAgICAgIH0KICAgIH0KICB9Cn0=", + "ilOd9dJuBwtaDrHagf6hJrSAMeUabnmQ98OVN9WQkhtBAPdfPPrNwN7FTGuAs0Z4Vx45I8zot/MpG0T0krX3eUhv0KJpGJf93iBqiPfEp0vFRMO9VV7n8oLrqkqUT0MkT/Lv8lt6DKNMuR7dDHpdHsu2sfbtLDC4TYyeq9WM9R6KlD5LHV8hA8sFxpuFaMlnvITihqNnVgL/zxQ84L6DLckHIC6QKfzQv6sfrnbyrGlyd/vc2cQLA8cHKkgSu3uWbvOWihxn+WTuEHIbAbbBdiZToiKG5WMxuMfSYUSs3j2vxsJsTnIHk/wfsd23soAZ1bRN7NbJLg84gRGvd1w50D426F8l0ryo0jvaMzizql7votNB/u/eE6qMotHP0JkHE/+5AhKO+2raX9I3Fci0gnob7EsmxPICzNFqppa475NBuHwIGccEiWJw0vGInPGr3bNFrq32xT6U1mIcHuvuv65lJuQ9bmAEdBdCd0/q/JdnOJBl7bhCrkW5XD0ysUZmlc7LC4Fs5z1JFj58vMATdzSAqu152EREQBO5JXe7jdX4dUlpHvqpZgFLWyKxUDl/oyO0ix1XR0MHJAVDjr6elWozgvbgtMWlPqw1wA7TNU/fjhUZRr1+vztKJMCQGW4dfPIftVuYJ21PK1AwM2ZUtQw+3frMxwghsY2dh4BEt9Q=" + ); + + + TELEGRAM_SKIN = new Skin( + "ewogICJ0aW1lc3RhbXAiIDogMTYxNzQyODQ3NzcxMCwKICAicHJvZmlsZUlkIiA6ICIyNzc1MmQ2ZTUyYmM0MzVjYmNhOWQ5NzY1MjQ2YWNhNSIsCiAgInByb2ZpbGVOYW1lIiA6ICJkZW1pbWVkIiwKICAic2lnbmF0dXJlUmVxdWlyZWQiIDogdHJ1ZSwKICAidGV4dHVyZXMiIDogewogICAgIlNLSU4iIDogewogICAgICAidXJsIiA6ICJodHRwOi8vdGV4dHVyZXMubWluZWNyYWZ0Lm5ldC90ZXh0dXJlLzNlYjNhNTM5OTM3ZjhlOGUxMTcwMzRhNzE3M2JkZGVkNWEwMzIzYzk3OTRhYWVkZjE5MTg3MzFmNGY4NzI5YmIiCiAgICB9CiAgfQp9", + "f7Ic3pnJr9Pb+EC1dwnZaTZtZGnb/DdMzzpH5lQFhZKMkHU40crm0cYUQUPnXQ5d3ozfHpYfndkPgMF8lByDMIkewT9t3yUdJEfRFp+bpdMronC1F6psxRAa0EkqlY4rCxonq3uVGYYm3XweutkxDtj7bZp8E9oH2POJRGIhvc03vCLKQHIn5W3CYIuh6exmEM0rvmD+OybkMV8RNYJLr4vfCpSXj0hcD564qboKH7ikBOFfAQJoXqeE5eaUJJWqSg+tkoX+ICB3INfV+xdSr1U6JSKhIuRAwIsTY4s47t7O1FXjZtIAtwB4eb3f9ltGhTF5A9DTqLrVTRCXbCESGZ0JM4Ps79CAarjMW0+cbYaeVTm+P4IzTQnGJOkBlKcwwt0HTJ+zKQHs48Ld86zfq2UP4MYCdotQs1KbPhgishqNP5jjVrA0KCCibA0UlhZZI06EnCGhK3kI4ZbVaszUY0R+jGuvD2XuF1iD6BcWZ/ja+6hhP4r66JWPfLm3VVSiEi12uXhTuayu0+4tTZ12q0AvlxWPfRq+kv05izhfzPHx2rgLZXkW3z0+v/Fn4y4WEVF3NLDit5huUkmimN/ACfWp9XJZ0xTZ8IQGcfp+yXF2pt4O3UxKAG16jBEXgi0X9muSGL2Bpv2LYQWi+3XDkVooi6IVHzO+LAgbC8KLA18=" + ); + + + ENDERCHEST_SKIN = new Skin( + "ewogICJ0aW1lc3RhbXAiIDogMTYxNzQyODYwNjAwOSwKICAicHJvZmlsZUlkIiA6ICIwYWFjMWRlZjUwZmI0N2RjODNmOGU2Njk3MTg1ODRkZSIsCiAgInByb2ZpbGVOYW1lIiA6ICJQZW50YWdyaWQiLAogICJzaWduYXR1cmVSZXF1aXJlZCIgOiB0cnVlLAogICJ0ZXh0dXJlcyIgOiB7CiAgICAiU0tJTiIgOiB7CiAgICAgICJ1cmwiIDogImh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvOGQ5ZThjZDJiNjk1MWQ1ZTgwNmJlYTgxM2JkNDZhY2IxOGY4N2Q1ZWM2ZjUxMzkzYmUyZjMzODM1MDY5OWQ2MiIKICAgIH0KICB9Cn0=", + "CpOBAguihQpQZwQzx+KsClGpsJRSo3hGKlxXupivUHgyV0VZ6pn9XgKAUnRHB9txEr5uVBZPVfQQKc9XVj+fI7u7bwvLyQy6LalEfjZSrnmuCljmEGdbZMITSMLVHYsr8MQWq3eFn12i06hEaVSM5qdWksdmwhGMzAmmZPVWgtzoPum7WrbjSBiBOJP4BwKhKx+ViDZsy8pVF7z80Zh/IfFFsa3yLBkfIGlW8aCpScQFoL5r9pzjIHdkkCvd6w32irWzinNKS5PwCEOtEEwDBiSRkvYEWsd+rZCt+Jg+Xf3P2i3xfjaMroEyCOYvZdkV3czQdVrC4HHFZYCAJi0IjfMs8xtZAJ9NPCV4qA43tUchPWzD6JJe/ZFJ7OK5lPE7aVxb51z15RxNPadpmEiR4XB+86obCEvvXoudY/yRA8AZm+326q7nCt+dTFxhtHtYOV9NGBrlDFkf7LpCCX9KOP2IBmBXPJfxa1Fg5iu5F3lC1+4X0yK2m0yc84FvfLHvBqSCHEPpXt8GdP3F3zQiqt8ipU66Pcuri0f3f6EQK2xYdbq6MvyduuX8d1EEiM1QulMOZuQ+PJTW3R5eKbAHc4koT4ZP8MAVFpQV97xt63G5KVTsXYpuK1IYvaqExn4iBNEuUyfyZR7sKW/SNzBWPB8di6DJZ0QhHSiIgbFlAQM=" + ); + + + COIN_SKIN = new Skin( + "ewogICJ0aW1lc3RhbXAiIDogMTYwNDc2NTA1OTAyMywKICAicHJvZmlsZUlkIiA6ICIyM2YxYTU5ZjQ2OWI0M2RkYmRiNTM3YmZlYzEwNDcxZiIsCiAgInByb2ZpbGVOYW1lIiA6ICIyODA3IiwKICAic2lnbmF0dXJlUmVxdWlyZWQiIDogdHJ1ZSwKICAidGV4dHVyZXMiIDogewogICAgIlNLSU4iIDogewogICAgICAidXJsIiA6ICJodHRwOi8vdGV4dHVyZXMubWluZWNyYWZ0Lm5ldC90ZXh0dXJlL2IwYTdiOTRjNGU1ODFiNjk5MTU5ZDQ4ODQ2ZWMwOTEzOTI1MDYyMzdjODlhOTdjOTMyNDhhMGQ4YWJjOTE2ZDUiCiAgICB9CiAgfQp9", + "lo2u3k3VE6OFENGpr2HYMgRBUWthI8P2//oxEKTMWSgMvGTpRz7j9hrOKyDejUCGFtX0/+WbxciLNbVOLRuJYoYhoEGUUgrtz1ol/LveXV0i0qOVMHLm+lHgJZR6CUzoV0PcLWmKwEjgq9MxCW0BBAx/Llls6+Jgqio+4zc1dn/RBAitf6WDL2DuXg/KSswTOeDIEY6JVQhQc2KfrHL0o66dX7lSePTSurn8vlXvMQaB0n3GWTwt2lEiFky4LNo90JNVBgWBd9RE9x/kqlFck0k0KJdStIz/shEejPGy0gts7jN55F3VrYz31E5Ica5MOSabsbdHvM/4KrJ9KVZ+gGmHNvBAo0bBbye0xqZtOnyOsb/2vXbEr8XpPh0/DEWukyCMLqWQbl/bLRlct7QhISnKoOzdTukYxc6QbFPsg/ARU1qn4hRpoT6vrlOPTOR2/cUKUIxNOaU4Tj3G9XRQftVS3P9iMS1fiPQHP1Cb9kbXCXmbREGEShKv9eFVVU5g8hSW50ftmlQ8nP1LTh09xLRu97547hW6WecRjS2r+9F9m2Tp7uOmdwM5aWHO7DphAASgYHmyKcaboGmt5o7xJkznwCkKWKX5FJAzVA+aw6wk/jma25fn1djuWHNYtzupK3qVlB/YnEGmjE8XzGf0q88WJuZBf6NNhdgqRk/oe6M=" + ); + + + HEART_SKIN = new Skin( + "ewogICJ0aW1lc3RhbXAiIDogMTYxNzQyOTI1NzE2MywKICAicHJvZmlsZUlkIiA6ICJkYmNlZjMyZjI5ZDc0Y2UzOTUzOWMwYjBhMTE1YjZiZCIsCiAgInByb2ZpbGVOYW1lIiA6ICJyYW1waXJlIiwKICAic2lnbmF0dXJlUmVxdWlyZWQiIDogdHJ1ZSwKICAidGV4dHVyZXMiIDogewogICAgIlNLSU4iIDogewogICAgICAidXJsIiA6ICJodHRwOi8vdGV4dHVyZXMubWluZWNyYWZ0Lm5ldC90ZXh0dXJlLzZlODc0MGVkZGJkNTU4NGVmMmI2MDE4MmIzMTQzODNjYzk0YTk1OTQzY2UwZDc0ZDFjNTk1ZjRkM2RmMmI2NDgiLAogICAgICAibWV0YWRhdGEiIDogewogICAgICAgICJtb2RlbCIgOiAic2xpbSIKICAgICAgfQogICAgfQogIH0KfQ==", + "OVJONWOypE5IaaKcTUZ7TWnMaLkTIiyU9h2x5X3DXPThOQw93og9dR4+6aTvy9H1DOA1nFC/ySZlVZCui428kCpTFlndLY3s/tJxfFrZkWGV2jfi4ZZQ+Cb5RUj7vJ4vLYNeXCunqC8bi/Ptuyv9Tyz9kHd5xS8gdkpDdWbOyqm+gwjHWVDuqg2QG1LU48w57fNVLoJ4c6FdzSfpSa//MkjEjjloVjIPtSeoUtrDQBO2xU4utYejIMSGlI9FLxjzS2gI6Pq45xB4RbqXsmo96CxvrFbj4+Y8Nm3Ili6kG95N+HeWOPIXvNnX76ZJZyV0IqcSuqhY+FcOg6sZORG+8JmE5rQv+daXG8hhM/t8so996cmPnJ8BMKorKTQXtmH7Uy4ZqEXF0cvQ9Bta0KYqtMnEzyBoUGagIBu42ctRrs4f90SiitGlU4YRVBkDlHNfawvEA5qUywlIW1nLeFriEk6VMRRH1EXOEetGE3wL7RxTq28Q/1UmUJw3gzejgyFjnLRHKVcpkixx7XTqoF7jps+tNyRgLbUZHJem0L7W71KYa7MWd3QJ7T8LdX1xGgv2kZly+4H8tyv4y+L+p2XS4L2E+s7PzT8MkiD5YYr08nuEhqSbnBiA7G/CkcF/B37QRVaRLH+uLJrCIzvdQqhJO1yejzvLm+eTPaMS9I54X7M=" + ); + + + INFORMATION_SKIN = new Skin( + "ewogICJ0aW1lc3RhbXAiIDogMTYxNzQyNjczNDUzMywKICAicHJvZmlsZUlkIiA6ICJmZDQ3Y2I4YjgzNjQ0YmY3YWIyYmUxODZkYjI1ZmMwZCIsCiAgInByb2ZpbGVOYW1lIiA6ICJDVUNGTDEyIiwKICAic2lnbmF0dXJlUmVxdWlyZWQiIDogdHJ1ZSwKICAidGV4dHVyZXMiIDogewogICAgIlNLSU4iIDogewogICAgICAidXJsIiA6ICJodHRwOi8vdGV4dHVyZXMubWluZWNyYWZ0Lm5ldC90ZXh0dXJlL2M4ZjZiN2E4ODAxYjcwNTIxYWQ5YWRhZTg4MzIxYTk5NzE2MjZhYTMzMDUyMThjMzllNjlmYmYwY2NiZWEwOWEiCiAgICB9CiAgfQp9", + "H7UZydA3X0iF+ps2zlrIh/hdlt8mANce12pyJLk+cl+Gtygak68LFLQMRrmS1zXUwengZBMyaH6A4ZJq57E6x2OpjasVGpoRadH2CfxgLftjRu7iK1/skhCgzUZnmfPNpGmIiMYlx35aG5T8I/MgTtxKauJCNGx+UzXzD1hSn+V0CHYgy2TYeHm+1LgHnZCHbOJqW7sTMZZ5wjGfjolAiV3ypJjaFqMxfixUzT686FWBFr/AX440c3OZMgwPYhrB94rJum0SaIqqemOrzA6zPJf3aLxCicKk5rbEYE4k1nRhEqOnG4f06BjFSFVbsVpisoIeVkeHpQcO3xwx8XeCEfLe4B07DnWg7gonoWkqWVzsqOgvcoo9BCqXoaxt94MgprE/xdPALdB4KaydYpvH9ueMExzIXSMrJ3BtcZGjlgOfMiBb9jTocbMtYTFFaMdUJW5XpvD7ijgJRoScO/WCnHSyNRzlxnYeoNLL2R/5ZVVXkh+84Ou01cTMQUdM2CpNGxdnKDOXaDF0q28n+6sgDMtwG2HuQITAqq8nNXQOs3FaBxK2n/rFsPVKBJMBkStjOQ+S/60Gtw32Ubvjix91p/KAo72a7jrsLRQeEUxPWhVwpPH10rZTl939RaVBFxJms+P/NFGGTDEKiHS+0fUZwvFzDFZPjGwQE1MpbO1eyyU=" + ); + + + WEBSITE_SKIN = new Skin("ewogICJ0aW1lc3RhbXAiIDogMTYxNzQyNjU5MzI3MywKICAicHJvZmlsZUlkIiA6ICI0ZTMwZjUwZTdiYWU0M2YzYWZkMmE3NDUyY2ViZTI5YyIsCiAgInByb2ZpbGVOYW1lIiA6ICJfdG9tYXRvel8iLAogICJzaWduYXR1cmVSZXF1aXJlZCIgOiB0cnVlLAogICJ0ZXh0dXJlcyIgOiB7CiAgICAiU0tJTiIgOiB7CiAgICAgICJ1cmwiIDogImh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvOTBhMTU3NWVkNWNlMmNiM2U1YmZmNGIzNTExY2JmNDJjODdkN2E4YzZkY2U2ZDU5ZjE2YTM5NzQxMWUwMTM5NSIsCiAgICAgICJtZXRhZGF0YSIgOiB7CiAgICAgICAgIm1vZGVsIiA6ICJzbGltIgogICAgICB9CiAgICB9CiAgfQp9", + "cY3BuEjltZ3hFhCNpzGBZg4qUx44Yov3AB58HAeDt83ez9Q0g9AhH8tSF7mk+iMBE4VgSPRPOJpbhe83jMDxEYuEH5sizvP4JNrkhztEYIRCFLF2FcOepEnJg69WgW1EYB1s9Hu+CR5f8sLsMOyVdCP7/qFc5nhPtiGivPEXvzHKpX0SV8PJXGRezphj1AghVfNRO/dtRvrPl6wwSbYzqzgztuJ39RCWzwx9dOWEpT0sGxA84RtaXTKPRH77zkQJ3gyo/h0sU2sFzfdG8l1XYuBJX1rcXyS6HVbfn7v0C0KmW2Cd7hYodAnc26QMiBz1LQobOmXXA8pQbQVOjZB888KewjP+WLxwg4rLnD3xrTzuha2LwZXUCEutWgWEDJnNjO0+BoQj0gj8fVehlF20LLmyzrtNNin+NJT8P2buVDnVhqbjLpQUL8nAzLllVStnebk36lpAh3qQvB/aR5SAdlgpd9GjoCmhjKx+RYBn9DL4vLkmHCNLgMi2WaHlp6JgPkj6v38QV7bRbVXHI/aHcdxZ70KSRxpwzMOK2BDdFtgQqeNnp496Y5su9XR4LsgE9WJG5S2Zp5ED7nR9b9me/XIC+06ORrUAwwvuu09HIQiYqESnjhBRrAIsi7VyDBVKN/97q6MMPEOrJnG8hPP/vZInyVvYZPd/Sg9tbGhT5x0="); + + QUEUE_SKIN = new Skin("ewogICJ0aW1lc3RhbXAiIDogMTYxNzQyODc1ODI4MywKICAicHJvZmlsZUlkIiA6ICI5MWZlMTk2ODdjOTA0NjU2YWExZmMwNTk4NmRkM2ZlNyIsCiAgInByb2ZpbGVOYW1lIiA6ICJoaGphYnJpcyIsCiAgInNpZ25hdHVyZVJlcXVpcmVkIiA6IHRydWUsCiAgInRleHR1cmVzIiA6IHsKICAgICJTS0lOIiA6IHsKICAgICAgInVybCIgOiAiaHR0cDovL3RleHR1cmVzLm1pbmVjcmFmdC5uZXQvdGV4dHVyZS8yN2EyZmU2NWM2YzI2NDJkZTI0ZWIyMjgxZmMyNjhhODk0Y2U1NTZkZjNmOGZkNDdlNzMxMmNhNjQ5ODNlZDIiCiAgICB9CiAgfQp9", + "iM33myFYDjRR2qBM8OHDV/ae2iK4ZeTr+euXAq/QBsLfQQVccrGC6qUNju/1gkKUHV98vk5e4IGvjvuCR9aITK079Kq+tUrmLoZeztbi76iATDnObVtc+Obxc1PiEpnsOvA5MRZ5zUkPgouhf30556PxYHo31Yce9/bftpAF/ix5qlA1W9U6oboSxBKvJmq8EJ9zwzfHTXPnjtOTAdHUhPz+OttmBl+u3V6PXLPrHgbnx6NKqrVqlbg6UZpylKx1+VHVbQT2MsFyIE5L4Wu5p2zaMR7K8cq7xsC/Rdes+HQcSmW62wYhH+dpJxZX5iakXxeCdZes06Ym2mIPCiD9+jB6cWn5TNWofH+nE87d9RY4yj/KL2+mgU/6hOPEMLn0zBA5aq8gimEbij2J8GOZVmPBeWGghsSYywtXl3LsucQrfkcn68rI+hRNEbidNEPkez6VwiF8goyIN17eLKSae+QcLpH3uqrhxXySmyafk0JcPvBOK5Id0jrUPiJ6KO3Rbb77HcdqyO03hNsHOWF2Q9FQOibjgQL710ztOp2NgEgFc/aUk252tT5MC/7vPTucBk2UEA9lgF5moaHN3nwvKwW7d4C2DRCz3ZQWtuFQooV3Bx9g2lZwTzFTeGEM0uuRMHRKboth+FDxsqitQfcbLAqeZa4Adg9E/R831umMXDc="); + + ONLINE_SKIN = new Skin( + "ewogICJ0aW1lc3RhbXAiIDogMTYxNzQyODM5ODg5MywKICAicHJvZmlsZUlkIiA6ICI3NzI3ZDM1NjY5Zjk0MTUxODAyM2Q2MmM2ODE3NTkxOCIsCiAgInByb2ZpbGVOYW1lIiA6ICJsaWJyYXJ5ZnJlYWsiLAogICJzaWduYXR1cmVSZXF1aXJlZCIgOiB0cnVlLAogICJ0ZXh0dXJlcyIgOiB7CiAgICAiU0tJTiIgOiB7CiAgICAgICJ1cmwiIDogImh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvM2EzMTdhNDVjNzEwNzNiMTQ3OWVlODA2NTE3OWYxYWVkNzJkYTA1MWI0NzNjMjBhYTMyYTFhMmUxYWJiZmY1ZCIKICAgIH0KICB9Cn0=", + "Z1JxCDSrN/VcYainqtkI2vY8Je34lZ/CV5MzNTMQ+gp4kMQoGACehF+0e/hzzdU2HiVk3Cn5utUdAerNTXblnVO9pQOEUVnq9MQkLghGF2vRMif6Q3k46lJZw74hYQaSPX2xe9cDGEjx+oL8ce13VM5cov0CkUBnjN9Qzgp7wJXH8nI/dKurxaiM7la4g/mOxeAPbW88jAYOfYHuyQONkoEcxdjW4/SM8r4dPaRYjTX0upJ3j3WqjAnKQyytRyLwl3Vqj82MYY17SeHbAuLLYDFY/x+DW5Mo+4GuuCRVYofxhXLn3uOkbsoRlknyxld/Zn9kpKQQ/WMKam+sjyJ4/cZDTNCMDrDTpGrelivsMeDaZ0lZqW/YiAKsLGh1gG8UNNOBw1zn/ARwSYlQdtMbT4c6hcWFpc0Q4yRwjwkEnvA3Jiws7htpDr4A+qSdjttS8ED/8uK2d3o2c2OR5bcFOfxTY7UT64I7GIR8Qqe95xBm1YWhaj08t04NR6sPQ3W9sGPfC8z4E+jG68c/YjZMv2z3ibSuR9KansuKhkYDcdGhlvxoxe4a4icQR/94njkYej0qbhqnjuaVmFTUgw8bZnMRkPOPQauma13JNbRO7CCLuzQxvA0YzIG0jEF6JqxqTod7jYCF/F2xkt9g9OaUtTDCH13coMrxOsCvB/DzqlM=" + ); + OFFLINE_SKIN = new Skin( + "ewogICJ0aW1lc3RhbXAiIDogMTYxMDU4MTcwNzgzNCwKICAicHJvZmlsZUlkIiA6ICJiOTY5NzViNTBiM2Y0N2RhOTUwYTM5MTgxNjU3MDZjZiIsCiAgInByb2ZpbGVOYW1lIiA6ICJHZXBoIiwKICAic2lnbmF0dXJlUmVxdWlyZWQiIDogdHJ1ZSwKICAidGV4dHVyZXMiIDogewogICAgIlNLSU4iIDogewogICAgICAidXJsIiA6ICJodHRwOi8vdGV4dHVyZXMubWluZWNyYWZ0Lm5ldC90ZXh0dXJlL2EyZDcwNjVjNDhiOThhYjI4NjRmMjVhOWEyNzVmMmM4Mjc0MmI0ZWFiN2Q2YTcxZGFiOWZiZDVjZTcwODk5MTciCiAgICB9CiAgfQp9", + "GcCkA5ZeqmUXdu7FV2T2ZgtIZW0X/1kX+bXXqqmRdJV1vogukr97YAhMiSKyW6gwVizRs2WZxvtyLhSw6Cfih1btRhRQ2tWzna3lHxYAockdQ1XsWyYkCQ3keBYcLL0ji+f7CJUtdruO4AqXSu1JdmaMT+Y1Inx55g0AukgV1Tr7WgCOBobDfMvpbg8dqIsmpOITQtegahKfeAlLNBhrzN5S4au6b8CdQHxfiR2lDv282yGG6gYqc9X62KkrWfl+adfmpEdJuddHqZWhnQXBu9iPvHDXdCAqgvPrjwsk0OpQrbVOeZcXxbjDxqDI5OZ4HuWKu716fDVYJVHaO+fBeqXI2URw+T/b8wIYFPii+yB6HPrL48SOYyQjAZeKGl0LYDDC1UTQmzxTORe+1siEoiauPjjb5lDBzDqR682Cmtu8gdG2/dErQE3bVQRfBPuyVfAPdRcFIiCx4ESnVDo3AyN+DYfls7+JLzJ38cI2TPMWtO+PKpWbfsszJlxdcv3OQ8myku+5UIVRTQdION8+i2C9Ho1una0Rs0eE4vFVVFWO0wKRQgd0DEnuEPVWP/Rk9KRjvd3/WNOm/GW3Q1MrrKB8K0zd8O0YvBd3yHLVZPYquSoBU+aJhO5jr0JO09MMSTze8sO3QHAxldTEOTBjZt8QRO05StiWFfqjFovKaLg=" + ); + + STORE_SKIN = new Skin("ewogICJ0aW1lc3RhbXAiIDogMTYxNzQyNjQyNDM1NSwKICAicHJvZmlsZUlkIiA6ICIyNzc1MmQ2ZTUyYmM0MzVjYmNhOWQ5NzY1MjQ2YWNhNSIsCiAgInByb2ZpbGVOYW1lIiA6ICJkZW1pbWVkIiwKICAic2lnbmF0dXJlUmVxdWlyZWQiIDogdHJ1ZSwKICAidGV4dHVyZXMiIDogewogICAgIlNLSU4iIDogewogICAgICAidXJsIiA6ICJodHRwOi8vdGV4dHVyZXMubWluZWNyYWZ0Lm5ldC90ZXh0dXJlL2Y2OTExOTBkZjA1YzNhZGE0OGRlY2QzY2Y5N2I4YWNlNzJhMWZmZmUzMjg3N2Q2YTRjY2EzOGYxNTNkM2ExYzciLAogICAgICAibWV0YWRhdGEiIDogewogICAgICAgICJtb2RlbCIgOiAic2xpbSIKICAgICAgfQogICAgfQogIH0KfQ==", + "p2CsjB/P32BlYnCusp75ylxa0EMbP0c6fQiq1XkSzkqBmFmb0m/ZHz0hCCo0fIX5TmkICF6UqmEIZ+pmSIAvP8/G/9Oe1CSf4hH7acInsN96ZGb0x8rf95iMJUtTWBO9R3EtT+kNG3A3NcOdvlknCEc8938MqKXfGMndu1Xk5WCfvP1U3jk/FVXa88eE8bW1Z7b33ePYQOePruLhwUE2bV4wDh0O64/l3hVVsLhL8yv9RyDTZWrRd/1aOFh6jxZBouTxI16uDu8/ZsgiPg+W0nuLa6kAft2BRprpsZvn0IHF3xnczfDL/aVX9TtM1W9RbzLE/tV0W2DuaKiK+Z626OHhgsUdvY3fFCGzTeazO3G3sUM2KOlIm62965w8IWhCE7qBpksMuNSSRva4r6Mmn5alrtrrX9sfNGwSto6ttOgXvvrsY2XKL+OmeYIYAQ4DGZNq8kJkQeGUS1WQz81aVgRiWjp1z0Hg6LYHBUYKb8jiKl2a0vCQce/VetHsa2lVCX4tgjzU91Oi3KG9R/xY/xeqDNPHaMgU7fIdTZFOXj8JjHqHV9JxjvhBeZv0gHGS+MXiRYWHWG3lNvL3B0oWVOlq2eqqU6KjRotWJs8fHRLPnvIND29TtvkHXUwh37Dpx4Uf4AEH822OkL8zTpp7zhwhAjSQMCNZKbLgEpmlYrc="); + + + WARNING_SKIN = new Skin( + "ewogICJ0aW1lc3RhbXAiIDogMTYxMjExODA0NTUwMSwKICAicHJvZmlsZUlkIiA6ICJlNzkzYjJjYTdhMmY0MTI2YTA5ODA5MmQ3Yzk5NDE3YiIsCiAgInByb2ZpbGVOYW1lIiA6ICJUaGVfSG9zdGVyX01hbiIsCiAgInNpZ25hdHVyZVJlcXVpcmVkIiA6IHRydWUsCiAgInRleHR1cmVzIiA6IHsKICAgICJTS0lOIiA6IHsKICAgICAgInVybCIgOiAiaHR0cDovL3RleHR1cmVzLm1pbmVjcmFmdC5uZXQvdGV4dHVyZS84NzljMTkwYzJmZTc2OWQ3OGVmOWJlMmJlMmVkNzM1NGM0NDQzY2Y2MWEwYzhmOTJlNjdlMWU3ZjNhOGU4N2RlIgogICAgfQogIH0KfQ==", + + "i4g4EzIuN7Wg9f/XRP2OH1pRo6w99SUw5k/R3esUjhHDaHrr6VXqc22aC1KIhEAMvAbKgqNMxOswEp+5gZmCAJ+gCuQQ+F4s+1W+POAF25k6p0EO/T676rUweBobdalMM8an+eOBOSVsIBKjenI1Xdz/UysWNXSccoybRoEACQULT4Gx5hy/qGFGP3+gyXLzoVfOQx69ZETkfASY2JNOPet7Z3wftF0RbK1pSbh9xn0xmr/qiAJsVbp0rITuo2D3bGPfWmfrjkUU5JNOXHzAex7KixAJa/DwHWATBmeFDzhre2KJP10avPMcUC7W1obG5h9tZtXOJtpuEKBpYt0X4XTcfTsnaKnEAbar/YEgvLczErc8kEW8Zjq0DWteb7niUbuFPtXvgl4awaJKOCIh9GevkRZ7fVbGUG5I0WvvyQd08XR0Lm/WmqcuBde8lu3Rr41lB6Q/ART2gov48UZ2+LFTmfJT6QOkJMr/YfiSmBMIGqWZKXMpLAxtKCcL2MfBLUR25GCQC+8cgqkp+Q4C7wqyr3QxeB56fOOggFyqcriRZo8C47rIvKRzDzILXyWMSIFRZfn4F4NEpmGkRRsRtBku8HwnIYtFItXldvo81/fV6YXe4G2aFRhU0iE8av6boxQ4XmDTA4CulBScGpoihMrcSnzflDDtftIOdvFQFT0="); + + PLANET_SKIN = new Skin( + "ewogICJ0aW1lc3RhbXAiIDogMTYxMjA1OTg1ODEzNywKICAicHJvZmlsZUlkIiA6ICJkODY1NjliNzg1ODU0OGU3OTJlYmJjNDM2MGYxNjkwNyIsCiAgInByb2ZpbGVOYW1lIiA6ICJPY2FuYW0iLAogICJzaWduYXR1cmVSZXF1aXJlZCIgOiB0cnVlLAogICJ0ZXh0dXJlcyIgOiB7CiAgICAiU0tJTiIgOiB7CiAgICAgICJ1cmwiIDogImh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvNzg2N2MwZmFkZjRjNWQwOTkwNzE3NjFiZWQ2OWZiNDIxMzAwMTZiZTc2ODU2YzEyM2NmMzg2OTUxNjU0OTQ3NCIKICAgIH0KICB9Cn0=", + + "iFdepbBq8WHQKmYlREoYQiByuGWWWgXv1NOxjBzPxSwSZzbujWRvwasgWbGCYs05G3m8AVKxjsecuZlfKdlgjJspvBV6QaFyYWAQwMiDhBN/9DRbuY3O+lvxzcjGH4jowrS6v6DDQOCk+b7HdNUq/0bXpKF6taV3tAe9ocojf540OdVCzwxB3b0se/nn4O4x6zZIvBN8mnzJNEB5uUlnAwRZrzxuFk50wZHBI1u5tLWr2UZ7Ed6W1wgeIAvygJdDdWaVp5IdvQGEcdtSMXXF1XoC1pWYf1pOSHt5TBH7OH/zI5KJ6xX1cy5EmyorJJZjqjJkntF4Ade7RieYT4g2FBwIco4LWTx3ACnHBB9bwu1iPDYDOK3JqWRmozTovt2vxq3pvAeNblYUlZi+GvhXCvWU0U49DwNi9Gw361Vy3JJXI5LrrNZD5eMYsMfE1l52zRf8w7e0i2PH3aJIAMVdj5CcOwb16drHeEitUT2v39BHLcNDw/MwMkYpm5B1rvspt3Y/4j67MX3ORmvhdmEVR/ztIPj4h8V4BQS0CIKNX6lOJ9HtgL33cP+PcdaVN6Mhqiqd4juxB2alToxJNtR/9ZTf8Kz7zcbGnjkIsJItBuUvzmYXzBAECglf9wzE9m81LmSpZRRMK9fxI78RPfktAZrT7onADK8WkM3STrEXvsw="); + + // Social skins + 1.8 + DISCORD_SKIN = new Skin( + "ewogICJ0aW1lc3RhbXAiIDogMTU5ODkzNTkzNzY5NywKICAicHJvZmlsZUlkIiA6ICJlYTk3YThkMTFmNzE0Y2UwYTc2ZDdjNTI1M2NjN2Y3MiIsCiAgInByb2ZpbGVOYW1lIiA6ICJfTXJfS2VrcyIsCiAgInNpZ25hdHVyZVJlcXVpcmVkIiA6IHRydWUsCiAgInRleHR1cmVzIiA6IHsKICAgICJTS0lOIiA6IHsKICAgICAgInVybCIgOiAiaHR0cDovL3RleHR1cmVzLm1pbmVjcmFmdC5uZXQvdGV4dHVyZS9kYzU5ZTVjN2IwNzM4YjU3OWYzYjQ0NGMxM2E0N2JlZDQ5NmIzMDgzOGIyZWUyYjEyN2NjNTljZDc5OGFlZTc3IgogICAgfQogIH0KfQ==", + "d00dnONViJCmrK0WdKODJ7tFb8vGKL+/GEq8NAqIa0jLNuCjz6pz+Rk/eoflg6vNnYRueD5c3f3M2ohM7dbggY0LZC9x2ef7/PYF57gRkA114DXJN/lZcq8vXQcZNFPqRiLlrMfzB2JwTyuCg5Ssoww3i5Fz4J0h9Y+ok8e9LfQzY5ficfyuo30cVB88ybQ5VS2Q5kxLgodrYgX+IUAJr+ns4Y48tKzPEVn4JGlJOLpY0tk8OMNTqFRlHw3cPMLQENeKb9OJQsstjsGHT4mvk7I8y/WdD0oUCj5xVUER/vgFBVwZuRJSBzFbUa5Hq8Z3JlriueQ/iCwR9t92yJGPQwB0kG0OH2wgolDgm2of7+1+67yZDk1X56/W82pxW5MEKjCnkfkGuGLvbydp8tf+6P4gX6mtWJudzibEpA+L5dfdHRJF5/l8FE4gqmbCKBhYdRT2keR/acB6bBF2g0vY1VCvaJe4vb3gFB4+FViDwnDhssLpHwgWxR//LEWrP4fmCJgLee2EYfySmMeVTW1gknHptIMJQtV92xxmft+vRi/WV3hqIkRNkBMI4+1MO96+buesKHUHg5yWH7TixcrFvbH8q3SAhQGqwV8Ksv44jSC8Bch9YP268DjruN6+TC/Lj+fGcFe9tErlbYM0hVCMUEeRDhQ3PzpThUegQmJ7Qk4=" + ); + + FACEBOOK_SKIN = new Skin( + "ewogICJ0aW1lc3RhbXAiIDogMTU5ODkzNjE4ODI3MCwKICAicHJvZmlsZUlkIiA6ICI2MTI4MTA4MjU5M2Q0OGQ2OWIzMmI3YjlkMzIxMGUxMiIsCiAgInByb2ZpbGVOYW1lIiA6ICJuaWNyb25pYzcyMTk2IiwKICAic2lnbmF0dXJlUmVxdWlyZWQiIDogdHJ1ZSwKICAidGV4dHVyZXMiIDogewogICAgIlNLSU4iIDogewogICAgICAidXJsIiA6ICJodHRwOi8vdGV4dHVyZXMubWluZWNyYWZ0Lm5ldC90ZXh0dXJlLzM1M2IwZTIyMGYyNzk4YjY4YzRmYzg4ZWY2NDU4MDkxZDcyMDU2ZTFkNGNkOGU4MmRkNjRiNWQ2NTcwZjM1MTQiCiAgICB9CiAgfQp9", + "aT/m2pZfq9tR1QwcIIgQTm8ytO4BRLXj5eZxZaFEr1k8IK2+utDCtfErrWtA5fNnWrkyj4AspPKT0Cw0WmgsYyqghhKBi9VS5CUCi/o2i8H6K76vFiYO5+5sKJ560RoPC/d2yJ/QS1qa6tbqD+8cIT4Hrh2Ni3ouuEtz1/MPg68p/EqkdNQEzNKE7xnuH9BFX06JLiKql35t/Mk/iMC3WdqCp1SuEmFE5sXEwfR+YpB3fuhmwi6xZj66TaVSZ0WFVkI1j09ROnVAcdhUa/yj4Q/kKBCeV7/4LsBeQhkr2noJh2UFDYPTSpQSgeNBlzgvSMr78CPLIVdpeyQ6MuoiG8HED5vytwJSymvgIf8v94tsDB8s8HfKwWIer7FoZ8kfY9BGhoXw22wCnmkRtzEVB+8wSpIKxwrjYMrSGiTIh71wrLkPi3nBVzy0lAEnQPmm7qePjET8R/l4LWT3kWojqiqS+YwMIXecSWTlhbquI1d8F9mFmDXYh+xSXsD+DqGpVlKuCn9RKXBrtaDIQtXu/5AxryQFgSSJOinxweOwlUAgFmiB6bO20KUfLM3YXdaxK7NNxCPVAoGb3gmvlsSpoGCW7KRobVwVNLQaCSzcXwE7WeRb1+c/xb918+b98eaGj7iIHicrxOMfuXOWEaDHDrrAXVydhEhcS6+3eccVZ84=" + ); + + TWITTER_SKIN = new Skin( + "ewogICJ0aW1lc3RhbXAiIDogMTU5ODkzNjM2MDYzNywKICAicHJvZmlsZUlkIiA6ICI1NjY3NWIyMjMyZjA0ZWUwODkxNzllOWM5MjA2Y2ZlOCIsCiAgInByb2ZpbGVOYW1lIiA6ICJUaGVJbmRyYSIsCiAgInNpZ25hdHVyZVJlcXVpcmVkIiA6IHRydWUsCiAgInRleHR1cmVzIiA6IHsKICAgICJTS0lOIiA6IHsKICAgICAgInVybCIgOiAiaHR0cDovL3RleHR1cmVzLm1pbmVjcmFmdC5uZXQvdGV4dHVyZS9hNjFiZDYyNjEyMzY0MDFlYWQyY2YzZTI4NjBlOTg5NDcwNDM3MTVjMTBjNmZiZWVlMDMzZTdlNzE2NzhmMzAwIgogICAgfQogIH0KfQ==", + "WWGuBEL0OlGmc7dhEiERLmv3MimSzTcg3cEqNgTVAQzGuidFN90YeE7EjUqAQXlgWEswXuXCJlMxYbM8szLkQ7tJiN7fQYKeqWeSU/GZUXTEuwkDudTF1en6lKx43i+iJEd46UMowBPO8inSjYJfLmMJn9+IStcol87o0TYce3iFjAHQtDootygAqR3w6LsYbABbfabFiHLP7r0FpqzO21xCyIJ6fcmRh8jEawJ56i0WuyaK+DuSa5COIYYQgNtfQJ1K4Bo18yuxFgi3uDvksK+p+ZfFJTdcKoWFO6SmLZpYLDaRL+dg5HZhYjfF29J8SBWXgDjJhjDXJ6fUpy5+2JEvKfZJHyGmqx4NrKF4Nku1Dof1L4e/m6P9Rzc79AjA0UpAX5OrVK7MaUm8LySM0b38F8TSHtLlK+BTiwbrxHKJZja280cOJsnOw0FI34g//0neLUv5mZlX6RT6ZuEebX6F3bhdCP0orqsEV8SgFjumGQmcWd4KeH8bk21ZOPoUeVoeh3HAHF+CbFydp8M1q5jAhupf4/bVFdmyc7lMMrL+DD/RqAo3xTbSbyxjWp21Hd0yIUcT83bAAIa+AyolGHmsI5rtr8P9zcEcsfMi8NEH0GhEqEKoYoSAzSNQ+6BF4GOcMbO4+MLtUZO6EPCA0pXwXRD5765ZvYIdVgi4HVg=" + ); + + YOUTUBE_SKIN = new Skin( + "ewogICJ0aW1lc3RhbXAiIDogMTU5ODk5NjQzNzA0MSwKICAicHJvZmlsZUlkIiA6ICJhNzFjNTQ5MmQwNTE0ZDg3OGFiOTEwZmRmZmRmYzgyZiIsCiAgInByb2ZpbGVOYW1lIiA6ICJBcHBsZTU0NDciLAogICJzaWduYXR1cmVSZXF1aXJlZCIgOiB0cnVlLAogICJ0ZXh0dXJlcyIgOiB7CiAgICAiU0tJTiIgOiB7CiAgICAgICJ1cmwiIDogImh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvMmExYzQ4YmYwYTIyMzBhNDYxMDMwMDY1ZWI5NDFhZDU2MGQwOGZhZDUwYWU1NjM0OTczZTVhYWVjNDcwZTZiYiIKICAgIH0KICB9Cn0=", + "ljAxdmighg13rgsWrkIuLmtPF/cNi3nVccEQSJD2FSwGvF7avKDuh9xV1ybM4XdHQVusdFSsdEhofDktszyMauUOvF/GZPxGGG+6WDG1HSPD3JmbUckYdd0608unBP8atA7TThUyP3tncnHhn9MtUbVwdq6WCtSCWw0LejLyyOHz4mSzMjcfbZUkOKhRf6zZ3ZjvLx92UDMiOFJcZ+HBXMIrpFgO2RrJvxJpVQYCFZptdCcPyuwh5Di3LVmy01ZAp4hfxCVOIjpcNMd0UcgjYdmDvGSFkXZty2DaVFma3OeowNZS2ISjG4E3GbBmPBSnctiT60ugrSmFQk2/9oHYeO4cs9cuW4baYOY2yHrNwsTWYjIoqf84wzzlpYxwWNejXYa6ckc3iM9ycgaGeCes3pzG7U01M7qQl85xigg5c0CZFgrjMCdCMwG8cp4uTtNY3TZg+jK7PtYE1QCrq6uIwBeBAN0/Me3lNgKEVKDXrsvtmUvTp5eerlm1lpQGIdF+L6HLV9ZBDWRV+gPEjgeZPdQaq4QmV3/88xs0SGScwdJkT3dRy6fdVnseYLZhSWeqP9cy28vm32JcTcOZMEbc6JBrwmj0POoE8PlllaSotCqW/RGopSiDAzH/tGhKTDX8XDYwK4eQ8jj+8frK1Q8S13wKCpdpGRGpQtZQfG1ntxg=" + ); + + //TODO: Circle dots for minecraft player + 1.8 + DOT_SKINS.add( + new Skin( + "eyJ0aW1lc3RhbXAiOjE0NTI0MTc0NTY5MDEsInByb2ZpbGVJZCI6ImU4MjYwM2RmNDE3ZDRhOTViZDFmMTcyMDY0OGJlMGI0IiwicHJvZmlsZU5hbWUiOiJQYWJsZXRlMTIzNCIsInRleHR1cmVzIjp7IlNLSU4iOnsidXJsIjoiaHR0cDovL3RleHR1cmVzLm1pbmVjcmFmdC5uZXQvdGV4dHVyZS85ZjcxNTBkM2U1ZGY3ZjIxNzEyODlmM2M1ODYzYzkyYzJjODkwOGMzMmFkZGM4NmVhN2Y2MWVkODQ3YjY5ZCJ9fX0=", + "v4HSztoVOn0TMBHyDymPBItvOpWs8z6twVamfdrE4yhr8HZoBYWzl+qxfWu+8+DNyBSCpN6nr/UQpFErdys9Kk6urIURx8mEeWDXcYOhXrFs7oNpXiD7UvYm4nd+vNr0xbpfQmSXBGIZ+eOei4ThbKdkSIB79mlq0ugbwxCsK2I8kUlUU6+KnsunPr80adcPu9RryAW00Bmta+eP65nIKwUWNKeLb5iHaPq+N/IZ5aKHmLFiSXiWniDB5UAYybkBZFuvosSr4TBpn1pTbEF3PtKpnPM/8mpt+97W1JcCAv0mdFZUr0hT9eMAe3U0r37J4w/RmLd0sCD7zOBX0pIPPIMrXOQ4DfuDbKSJPXyXiLQQrWCHYnOO8+8kiQcoQ427trsb2y+jMwYel2GEU6gS5zOdkkVm8Je6tNxgA8vRGqA8ABW8SVQz7y5spk2CGiTQQbV3EeJwKcZHXAAplkoSB0p8fRE1fEY0+REoETg5TbguZnONm1+PdW/LdLifL2tGClSz6Nb4D513zZuJaFc/dQ7yagJR0cFkuWVuI59ZnoKqiEW+tMsrhn7QwCwGN6eASHd9seNvnTXsGOyZ0iOWFCay7JWOGSMr8iGiYCd92kn4r+UbCJ+OtokHzxFIoEHr2hRnN6thye27/tpP9Is7cmmmrDAKvecGtYfsrCVmTIw=" + ) + ); + + DOT_SKINS.add( + new Skin( + "eyJ0aW1lc3RhbXAiOjE0NTI0MTc1MzgyNDIsInByb2ZpbGVJZCI6ImU4MjYwM2RmNDE3ZDRhOTViZDFmMTcyMDY0OGJlMGI0IiwicHJvZmlsZU5hbWUiOiJQYWJsZXRlMTIzNCIsInRleHR1cmVzIjp7IlNLSU4iOnsidXJsIjoiaHR0cDovL3RleHR1cmVzLm1pbmVjcmFmdC5uZXQvdGV4dHVyZS8zM2I2NWQ3OGMwYjI5N2RhMzgxYWJlN2JhZmM1ZmE2YzFhZWVhZTY5NDcxZDlhN2JhYWQxZDQ5Y2FmZjVkYjkifX19", + "mKqD4+2/uXiIjNmtQDcaGoxghxN3d+YFX5VgVHO1whwWSdEzRtNj3tw5CJOyBZVzQh6GfYqqi38ylfCiBq6t3JAYfaf4BxsDSKyq4yRfNb2JnYQoXGrhIhwMqEEyieXoJUshnBXpneASDf0a+BE5hN29l2vqQGs9VPKggqbt2zpZHyUi6tQMlwOiL+jDKh1bcSr4Wl1Ad8JC/BhUXytOR5u0FWm4vOEsqq8Td7S4Jm+XzgwxogtrpeVhRMFwYL7snjehYF3qh1W9p8PNmJGtZ9AApUctc/qEVnWeCOnDAaKgqozj4ruc4Xk2KMXxj0GmDS6b65C3m71MG+cW/0sS/Rx8vmif9SJum+E8C0X8inNr1nui+3ulmwqC3x0MeVsp81cr+LJIA2dcryKVWV3W6hkYuc3OBUjxrN6NOP495fEsPTFx33eop+pajS8g8Re4drNYHUSy7suzDOq+Yv1XM3hOASN/msCU79/tj1G7HIQ2+RHz2eFZlUWC3IEX+5BM5cf7uK1hhkkbejUkmQSblFGeuTnUdV7Yr6kmn0kXQbHAOIrRvw8d91x1lHoX7yjh+HbG4+RymOcm09MJAfdaut7Q8fINHM7rsiHOT6P0Tj7u1UXUUT9w9YXkVgEPCpjSjsjfkGblq/bzDzg8d/es3aZd00WmqFGjlNMx/EKVf/A=" + ) + ); + DOT_SKINS.add( + new Skin( + "eyJ0aW1lc3RhbXAiOjE0NTI0MTc2MzUyNTgsInByb2ZpbGVJZCI6ImU4MjYwM2RmNDE3ZDRhOTViZDFmMTcyMDY0OGJlMGI0IiwicHJvZmlsZU5hbWUiOiJQYWJsZXRlMTIzNCIsInRleHR1cmVzIjp7IlNLSU4iOnsidXJsIjoiaHR0cDovL3RleHR1cmVzLm1pbmVjcmFmdC5uZXQvdGV4dHVyZS8xMDU3ZTUxYWE2MmFmMjQ4NjdjNjc1Mzc4NmYyMzRkOWJlYjI1NDEyMjM5MTc4YTcxODZkODE4NjkxNmU2YyJ9fX0=", + "P6gT4sSTDPKon9h+Qp/JEK1minlQQRi0ReIsYdYFzHiVpOejPxq4MU+0Ebmvs23mgX2tgqUQV8oeHK9xNCoTB4cKrLMq0U7JJ4C6ShCrQXL3Mr6MilVIDUbP4Fvj9uLU9vFCEiyHVnYwKlnIsnDxnOOBFzki5TyaFTVt2LeNrlso6eh9ARpa5PCAevtEDDrZ51ftvoI268RrbQTfgE7coiDYAcEzgSY9Lm5I9vQxIN6VWhh/tUxHHdn8u1eDIbga/I/EuQZ6H+V0E3THmR55ob4mKZ4e3TYWWRRlOIZPOdFcPIluVdkVZG03cQfw8RYsON/dazBnbME55NTF8U6ovyDWcwYhCEJtRtA4yGMOocX06InRDOkmFk8FcomtJF0WFSSZRbNfxEmG1XXZx1VtKX4eYR97Y/ihOBilN+Aq5yQ2AB+JvEPb1NFiQHdu3mQ/E4tJxKgsorFd75xbPBV7A/mPsrUV2GHvLFJzlBQGDYJCWqqIEdRV/V417j0XlpM+D7UBiIekcsDo2ajOg0v5mQqGF5d1+H16K58PgAOkPLmKwy3lTAnpPWhSWfcrSbkon93eezlD6eMZie8YG2ucaPR9TXYXRwLxK9DrCx5ZfzQV4lgeDSsL2i8kNnYmTLZ1DnsVw8IwWifUFGwwapHFWO1thdy5yifjaa/AOWYTJQE=" + ) + ); + DOT_SKINS.add( + new Skin( + "eyJ0aW1lc3RhbXAiOjE0NTI0MTc3MDY0NTAsInByb2ZpbGVJZCI6ImU4MjYwM2RmNDE3ZDRhOTViZDFmMTcyMDY0OGJlMGI0IiwicHJvZmlsZU5hbWUiOiJQYWJsZXRlMTIzNCIsInRleHR1cmVzIjp7IlNLSU4iOnsidXJsIjoiaHR0cDovL3RleHR1cmVzLm1pbmVjcmFmdC5uZXQvdGV4dHVyZS9mODZiZmEyODRjOGM1ODk3NTFiMzQ1NDA1NTc0NGM4YmM0MGVmNjVlYTZiY2RlYzc3NDg2YzllNDE3N2FmOSJ9fX0=", + "LGisiuVbSaI9K2dXN9CsV8SxuXieWvCHTg1mdjUh744AYQBbINiEgEbXiFz3cQXzzJttUAW8MPZyBnl4qxJr5QRXd4mB8bOd6nA9eimRPiCIpS8QG6V5YZWdyEvKuV+xpdWNkB8I4kpgkRFBmYsKNWeg3xhmgeA0QP1kpadGKU4oOMb5vzUzsIVbyycjhtGcRNuGKjZaNoHVssuTUpi83xIqdCPI353rsltncBY4Idheig0cUzBXqvLX0K3pVxVgg+jQxRPRlGdLhiMXXs6IkRj1glvcZO4MEMg4IfA/W6Vq4UiVG6RpubS53jDJDt4G4ZrtSVX07rQOowHlnY8xIgtpSAbW2iy+uHu3mvv4lWATZE7irU3QrRg7PUSZYSIihqY+CWp8eJwhs+JxTTBMqCzfv5HvZg73WVj2003JTIIxtqTyrlBxIa+4DnPBhoCJ+N0v7wmLdZQC+PsVaRAC8nrlhgDewfglW9HHhqU8m5LVa5gDyMlkIOo6w8cW3mOCTqndGNf4GmDVCbli5Yu5SptaZXvibCp8HcNmkJdP6yf4h/hKPEvOc1QzQOm4L5+9jJxGtpZA2+sTDXqucI2TPy5XNxd9+GaZP9J/xMiwihqeGYmNXbjCJdFSE5NX71HH0NbIVQu5G2VIFccuKkz0iDP1vl60ZiHZdVhn3DcL1gY=" + ) + ); + DOT_SKINS.add( + new Skin( + "eyJ0aW1lc3RhbXAiOjE0NTI0MTY3MTU0NzcsInByb2ZpbGVJZCI6ImU4MjYwM2RmNDE3ZDRhOTViZDFmMTcyMDY0OGJlMGI0IiwicHJvZmlsZU5hbWUiOiJQYWJsZXRlMTIzNCIsInRleHR1cmVzIjp7IlNLSU4iOnsidXJsIjoiaHR0cDovL3RleHR1cmVzLm1pbmVjcmFmdC5uZXQvdGV4dHVyZS82YWM4ZDlmNjQ1ZDU1MDE4MzRkZGZjNGY4YjVkMzIxNmQ5NGYyMTEyOWE2OWQ4YmE0YzJiZjE4YzE0MzEyOWQifX19", + "D7ub7tuNpCdQckdl9tMJMoSF9XfEAhL0UA4hqMNUcm++uHJviVXbI9ePlg98+N5aisqzVj19/Ld1DaJENFH8eKtQ+lhvzS6Rh+x/JF/QGfDGbWSbx9J9H86LvJpY28hQ/XJ1cFSmtqK5xlnXBNilFj+sAtqCJ+KRdPzwnhgvMNqFMmy5op4qjHaQH4QN997DDF8RWt/9dMzoBDS32sr9RAwzyQzuRsa2mHyMbrrPzST78tcyBWk/dddE5zY9qdt7sDtkar3hDOEMgrid+ChxmAlh/LulaXhpW2S0XEsUEY3uBc58iNrnIWaQedaYYaFFdXPe95BPMaMXtgHblRsOhWlvTAXv9P/CB3v0PKlbfH+kFZyf/OgHfkZan575dAdeEl5mVdT6h7rqriau3MIj/MPUX76xMY+0cbNUGG8Dmw5s6Fw2CnkBuRJWaf9NlSynxm0S/K8BqF/UdGCHc3BVYJ54Bhc65KyN2EONaON2OT2p41Ssvt0Z1UEdb9w+0G+pMYJ9qp/firkdsyQC0VQepymxTDvsmhrA+MC/fb4QL47XucJIFGzhi/qbxj+AjKSt6jhbqYUNE74Y4S8U6fsjIko5dEiQ1eVhq+TOsGAiF0M5M84Jpcyh3B/agvJLic4zIwR0AEE91Ok5ZM8hOimhQf206XvYItw3FqNGjdOsiPw=" + ) + ); + DOT_SKINS.add( + new Skin( + "eyJ0aW1lc3RhbXAiOjE0NTI0MTc5MTAxMDMsInByb2ZpbGVJZCI6ImU4MjYwM2RmNDE3ZDRhOTViZDFmMTcyMDY0OGJlMGI0IiwicHJvZmlsZU5hbWUiOiJQYWJsZXRlMTIzNCIsInRleHR1cmVzIjp7IlNLSU4iOnsidXJsIjoiaHR0cDovL3RleHR1cmVzLm1pbmVjcmFmdC5uZXQvdGV4dHVyZS83NmNiYjYzYWFjMzM2OWE2NzI1ZDQyZmEyMjM4OGFhZmUzYzFiM2YyYTE1MTlkMTA3MjE4NDMxOTgzNWNjYyJ9fX0=", + "QUWtd7snPe+R9CWdOgAVlagJE79wO4NUGouqctu+/38p2L2b8PRyFydPURaN7gimsBd3+XM6fd2SqS5goc/wj/YXn7FKrIAWP7Wlq1+638006wKaqtyeIXPIOEGBt5fZ/ooYvKDlVjEkyZ1MHwhUVtkmBDUGkvG05WKOJ0LscyCuUw93qfE9LJjowMLubIw1Aq3gSo0dmcN+KcSebHxP7ppThE14BZBrUr2h5zbu1LLYSDKgjFiO3BFkVKFTXtz8P3/kLprQUycT+ojGf8aye2WjO9GlEkiEEj/MLb31B8ImbOZcFWpmqEGfxctKyK2UNZdVrof+Y2qKpZMMVcn6H1SWCM+H/vt7y0wxs9j6kk+xkFTgQJUJY4Y+lBuT+id5Zm0iP3Ua/dCauhlQNezWvCnvx/ICKtGaibzpsouScj/2XMapnQQBNnurTK6v5viDvlt3vF5sdg/pRYDtqyKF6j0prBjQJBayAmANMIefAVYKwGyHONg+JJi72JEm9srIamp1a3ijfP+gYj/1wKtu38w4t3Yfbr7PRO5ArhZbUKvxw+nIDRPwK41SqARU/j9aWVtsud4ASigNno8KNndH9Q/RIfXXukKBNi69PRvPgG+FKhrpN+U+13Zcdzx0mtkMK+ZGb1Qp05Ko7gDfCFawWQE8wKiFC6mIWzWVSeCMqdQ=" + ) + ); + DOT_SKINS.add( + new Skin( + "eyJ0aW1lc3RhbXAiOjE0NTI0MTc5NDUxMzEsInByb2ZpbGVJZCI6ImU4MjYwM2RmNDE3ZDRhOTViZDFmMTcyMDY0OGJlMGI0IiwicHJvZmlsZU5hbWUiOiJQYWJsZXRlMTIzNCIsInRleHR1cmVzIjp7IlNLSU4iOnsidXJsIjoiaHR0cDovL3RleHR1cmVzLm1pbmVjcmFmdC5uZXQvdGV4dHVyZS9jOGM0ZDQ0OGIxZTEzYTI1ZGUzODg0ZGIxN2Q5YjBlZDM4ZGY1ZDEyM2RlNTc3M2YzODIyZWJiNTNhNzYxZTMzIn19fQ==", + "gdr3b0Zy/uOlU4VdDuAmnPGhKlg9qImK4zj0qoisJZfiVYrPNPeQCocxVvnkAYqsuTsoe7UUo5/oW/G6Z6AKw+2aapkNbUSwxhdCb2vLmnIt8WGhxTxKcd2OEdCnAmCNgtcF8kF062yK8Enoni2eJI2oV+7MektoFWV5pWBkSmhNMBuw5AraYv9S0+zJTYjX0eANTuNXV+VKnfzMCcKuyOBwqXhNMzL9vmvXTMBJAr9bYx/xH3POO5xhGRrW4NyuWSE9SXhV4NngSR+59kImfZmSA6d9kuK26feZrfRrAME/UV2rjbnT4WWumYzvrroZKJBcq++yBEsVluEagkWzs8UXOtOiNYttp4ETg19aYObXdQSLGFRzTeVCVw4cHVSX6Svbiie/Kyr+s/5fQX7/LCs7uVlclPMrabQiam/DzDRre3hbEHXTfiUCLFQLjyqOQ1+gsPqWN2E/HMj0I9gbKL6qrgRVstvTf97UXqXxXudbOC3EthdgAM4n/lR8s6RqmqwzfdkWAyvYGW2c49tImnEtaltwhzeprURNy/dEbLkU3KYfXx2nVHO7+d67WJscwHiffyxDpLwTWkclIrC7bl2SKyfib1cElDqzXNzKYeqZ595PkiHeBBRjL9CWLTlXcLMWuJtdqvquCXt6oJ7EtalcVhKE6DHXdtBDDYDaWpA=" + ) + ); + DOT_SKINS.add( + new Skin( + "eyJ0aW1lc3RhbXAiOjE0NTI0MTc5NjU3ODgsInByb2ZpbGVJZCI6ImU4MjYwM2RmNDE3ZDRhOTViZDFmMTcyMDY0OGJlMGI0IiwicHJvZmlsZU5hbWUiOiJQYWJsZXRlMTIzNCIsInRleHR1cmVzIjp7IlNLSU4iOnsidXJsIjoiaHR0cDovL3RleHR1cmVzLm1pbmVjcmFmdC5uZXQvdGV4dHVyZS8yYzkzZWJjNzc3YTg3OWVkZWViMTFiOTY2MWNmYTZkNzdkZjk0ZTY1NWM0ZTI4N2Y5NmY0ZmY3OTI1Mjc2In19fQ==", + "jL/5arN/cnJbD/DZG9HTo1ckkwZk+XXYUe6QUqbZ0QAm/wecw/mDZqvGwqwnngsgyg0UelxPHvRK3J3z3SdVq7Kavq2UdGkFLr1fe+34bxTnzricHXs4baYDQPOunmbdHgDs+7wwjYJbuQ4nNRE0vQsCmMAe2epchFEDRsiWYuBS0bWCDtQzCBJasGridmH8MIpBmicKQ8OWor9q9T/Pvxh1KEJdpFJuvEGS6xA1J3GxuRT6Iq1elATJNhW3P0MeHU5f/C8N42clLy9K2W8DGm0VuDQbYZmBCaxYcIo3kbkAVVZ6LGHfO8q0kxKIq9q+qXcmn5TQK3BmyjqTGY3PFYRVR9thgA+LWk1s1Ln1jA6ousckJmQJa1eW73mRt91fvRVAMUGm5qrwScL6q2pe3BjBfB3OnilSR3x2cdwM3WkmfN8VuELykJvxHIhDXGCxI5Xg4ghPyZvqW1NNTJmCUokp/fEt+64ZkXoqXzzV88pGZXuVC3ySgg4hdhL4he0tUOVQHttls+lQ2id6R3XaHdh4Hlk/EjSDM5O9auenvKdKAis+vVUV2oqJ+XGb5juD/MOG/INieNfuhQArWeTxyeufsOj8llWEcyYVRVcmJJfjrAagSLuY9OfoNVlSBM2wP92tzQUXQrvHM+mqw9gDlhudOnJAyP6iP8bVsqPN1bU=" + ) + ); + DOT_SKINS.add( + new Skin( + "eyJ0aW1lc3RhbXAiOjE0NTI0MTgyODg3MzcsInByb2ZpbGVJZCI6ImU4MjYwM2RmNDE3ZDRhOTViZDFmMTcyMDY0OGJlMGI0IiwicHJvZmlsZU5hbWUiOiJQYWJsZXRlMTIzNCIsInRleHR1cmVzIjp7IlNLSU4iOnsidXJsIjoiaHR0cDovL3RleHR1cmVzLm1pbmVjcmFmdC5uZXQvdGV4dHVyZS9lODQzY2ZjM2ExMmNiNjQ0MWY5NjA5MDIwNjM2NzI2NTdlMDhjNmQ4MzQ0YjUyOGE4NDU5YmQ1MTYyYjJkNDgifX19", + "nPEbxncNxOm4I6BEsRQ+nsSy5qXKsvKkKLTYHUkze9fQS5JYyiTgAuN/ouljx8fBSbEBdFWxFZq68WxF5h3QDIX7O9x2OFtx9L7vURndZ9pACBRJehy2Kt50eLlEeNMfg1z12J0ODQ36fKbujUYK4ad2ZkM+IOd+QGRV2EDRqFpKC4NMIiXnQ40RYo5GJBAIuW96kioCvaN7+jbpyKW7ub9RAj7dVlXeBbP7cCYvPHb74Ww/lw/EhcsbrwH92eqrApr/oq0Aa9MoW4FKLsEejXvYFjzn6d44uPddwjkcWnd0B2Z8Z8PU/ajS+ZYQY/RqQKRo72bjjPKmn92A19ULtPTFTSOsxxVmLTSSFbYqujt4hUd7BEcDlFcowfhdXtUQWYp1c0DV63UU+dkp8bmnaSCHoG+goyJJN43eqZwSiln2UzEGb+it/wSE3kgsy8q2X4pNgx67ZVUW1ZdRomsBIO0WoanuYoeCNXKRzwMj2mygocdlSer5ZmsnvqG8e+zt8j4iytYDRZ9AWu4euHPPYPbWozAUUbqzsAkogcqa29Bz0mEbr56Per+4806tmPrg+kheI/pBvqCv+HBMRM5ZEEO9FWkTKl2hvr6t6uTNuXFnlVkwspEJaocE+8JJ0E4WDW2mR997uvYYbohY/HPMUG6cK05SwghM9OhQmD8L1Ao=" + ) + ); + DOT_SKINS.add( + new Skin( + "eyJ0aW1lc3RhbXAiOjE0NTI0MTYxNzkxNDYsInByb2ZpbGVJZCI6ImU4MjYwM2RmNDE3ZDRhOTViZDFmMTcyMDY0OGJlMGI0IiwicHJvZmlsZU5hbWUiOiJQYWJsZXRlMTIzNCIsInRleHR1cmVzIjp7IlNLSU4iOnsidXJsIjoiaHR0cDovL3RleHR1cmVzLm1pbmVjcmFmdC5uZXQvdGV4dHVyZS80ZjE1NWRiMmIwZjE1YmIxMThjMmNjZjYyMWI5Y2JlNDBiZjQzODk4ZmZkODRhZjczMmMxNWYzZGNlNWM4In19fQ==", + "tXZ/NzLISCygr4aGFLVwW6g8lZdoPruN472pVGHepHU+e+spVjOoQQ/vXrIl2nO5EZe4yVsXYDGZK7UD8v3pNfjyXdwAdaRplgQy4B71dvpxoookgN6ytbkr3EV0WucsNCpJPVEAWN8P1DGYVU0lVWyqdphfmbqGaTQOtJonS95TIbfJvmropA86Uc3s6mCOGceb6+wu216IGOtQ1tnBI7wJJF6p3nYm2hXKPDz/ulZNUb6A17T532hfLNRk7tWaPsjzYnKdTFvpVzuVyulfUPz0cxfjQPAreU072/GxKxk2eTlK6qBCT4hOBa+jlnBUUuG8JIL1/HetF5e+svs4LcMzVh1ZSnPsu6ucEpN8VESDK6ErUSuxIm/f2FnaR8eHaqdJBd/1xaA2jAILNP/Y//4G72BdnMnFsv+rVptE+V+yWzg0Pvlv3I0FqGNc+fZWmP4pqjIUd2T7LjtztV7MyBDECg2ASXRhmaaldjKcZAjgaOyPjYkQ8ydFgPMrQB/xR4yiHnivguJWG9ReuwALI480ZKw5VM4evp6JhvYGBkgnrvC+AKGX+gAZhfAnIT+KdUXAJh3LYfy984e1OQQqNCOg+lHR1aPU1RbtSEN878gqYNbMVbZ7Q5fAEo7kz9V9uqmHSrqQ8w4ltUO9W4zbMYJDVVdVAWbzF915ohYpgp8=" + ) + ); + DOT_SKINS.add( + new Skin( + "eyJ0aW1lc3RhbXAiOjE0NTI0MTgzMjE5NTAsInByb2ZpbGVJZCI6ImU4MjYwM2RmNDE3ZDRhOTViZDFmMTcyMDY0OGJlMGI0IiwicHJvZmlsZU5hbWUiOiJQYWJsZXRlMTIzNCIsInRleHR1cmVzIjp7IlNLSU4iOnsidXJsIjoiaHR0cDovL3RleHR1cmVzLm1pbmVjcmFmdC5uZXQvdGV4dHVyZS9jMGQzODkzMjYyMWI5NTIzZTlkODdjODcxMzEyNTk3ZTU0Y2QyMjRjODQ0NmY2NTE0ODY1ODE0Y2RlMzhhMTIifX19", + "huZ5VsNJVXyj1jijC2KE3rE/XbF47jfj/dApSKRqMbTmHQhi3AEFUAetgN0TsBJWaynz/bgADVTY84WsDeeZyW6u1FZHQtOyvq6zxVCw2L1tFrjO7Ts0AYXpNvaZawz+r9OuM01Y62z9oK4VwA7e9oFHDSuo4mExcTgd35cqyxJmqNA2k5xMh88BBiKumJNTenzTEqfQaaWesSmRJWnxZ09zZKhZb2E0m4ekymZPKZWPuxxfOenaFWlpyltLnx/2pC7VRkG1v+zoBe/VmfsEtu5qWPPS8UPtg1Fpx+Q3GtxIApGj0Ni/DiKkaOmOY/5HH9uYD4BtJ3NjXEFCWbkQOXEgLrgwdstRVL53opC3+07QZTbnXVNA2Ua76Gu6T8j+KMxpA0+q0nS+FQZCL2TEt2Pm9nsAZx43kvQ/iA3hnM1hZ64jSQ4nj38mUJ7bnmqM2bcZpQMtIDzwMwswMLh9/jpYFZBK9p5tG2TW91RjSne6R0sOyzZyfOBX/T8oNohBCSVokD4+8SGyBGzknUb1VE0YOZ5HOj3N7agGxhWyPB6DrYCUT8hljtezFO+iPBSBLVo2yuX1PMrrQYB9ir+rTc7mjOYWmL6ENrkSN52fBDCd4yLhPZyU0AP4ov+Nl175c32e5f8Ihhz7IRnVhNDzOE12WS55ynn1IofblMSgfPU=" + ) + ); + DOT_SKINS.add( + new Skin( + "eyJ0aW1lc3RhbXAiOjE0NTI0MTgzNDc3NjIsInByb2ZpbGVJZCI6ImU4MjYwM2RmNDE3ZDRhOTViZDFmMTcyMDY0OGJlMGI0IiwicHJvZmlsZU5hbWUiOiJQYWJsZXRlMTIzNCIsInRleHR1cmVzIjp7IlNLSU4iOnsidXJsIjoiaHR0cDovL3RleHR1cmVzLm1pbmVjcmFmdC5uZXQvdGV4dHVyZS83YWQzYTk4NmU4N2E3ZDZjMzk5MTNjNmM5MmE1MmNkNTI0MmUyNmU2ZDc4NzRhYzVkYmFiMDdkODNiYzE4NCJ9fX0=", + "QwTBMrsbG4EGg5GnaYGyWy5S6G7UWJTTafe/22OMDEsmIy2mcaPzTRHdxQjeWPa8Zk5wGlp7ehZMbC262DRdDG5Wg7SKuAkxNdow/u8BhrUJg4Z9nQhfOauoN2tk/F1j+isV+xVi58EsEhhsr9h/1s9vxJKI2GBJJUmTjZ8xzYmcsihpoM4LaHKRu8sXWQ1MHa5QBgqzOy8UPRabFFNg/5GT8xo0UqM/5FlsYMdiIPsEdOi5bMPsU6ZTco/hWpqTMAlhDMw3hLUxvknnQ6Pf1Mi6GOqTSucaKggAyrj++p9LMtihwBOvRHhWUfIPTKdZ05JllS8Q6aZioOqVbsd+GLHYZp/PKtwKNC62rPzpqZMIBw3HgZ5ciQhSmDMr/l2dDUKEn/LIAJew9P+GXVEpPTAJSLy2IkcEKzrtU5ZSTmbZwzzldviK0+tPVCE3AzMcnYqoVbj4uOpo9Uo/uaunLWm8/PWcjRw3qy8c3czxC1xVynEDA5J6wjo8oqjSnEOuHuJ6cFLCYUf4QMlRmVIaA4lllAOOr+68QEHzek+DRc6rNgkUoqCcHF53YCfH7JItpSxxTZ6snFS2LI20KFUp93DibVEkxifkyQLbqB1OAcyDXkji8HJ7IKUMAUKoNFpLL5eANJsv/96P81N16rGA3THLe5iz17L5xVX/hpruKAo=" + ) + ); + DOT_SKINS.add( + new Skin( + "eyJ0aW1lc3RhbXAiOjE0NTI0MTgzNjk3OTUsInByb2ZpbGVJZCI6ImU4MjYwM2RmNDE3ZDRhOTViZDFmMTcyMDY0OGJlMGI0IiwicHJvZmlsZU5hbWUiOiJQYWJsZXRlMTIzNCIsInRleHR1cmVzIjp7IlNLSU4iOnsidXJsIjoiaHR0cDovL3RleHR1cmVzLm1pbmVjcmFmdC5uZXQvdGV4dHVyZS84OGNiOTNlOTgwZjYyOTMxMzYwNGNkMzMzODEzOTRjNTA5ZjljMTIxOGRjMjYyM2Q2NTBlZmI4ZjNkMjAifX19", + "FqA2ErdpdSPLYrb+O0O1i5dxEr9ZD7ZhaeiSZmU8QSf6+yA8eGo+KZo0N7EHC6YFXnxkgySFqJYk7itcHQ5bLRKpKCaSKAXP4XX5a94/7x6lNa8ev82L+Er3A/mH/0cllxmngqLY5vK8Hej09NoMMNNAhtp+f07TkqLPCi3J6G4mFK4zHAId1gEIEyj7JxlTDeOeU0MRUE4bbngyt2h5VsGpitFaYWJZTSnl8XsXr+6/diXk1nM9smKmmwIv8C02Ufdw3N4/fB93qWfuDUmpd4RLck6XJpp8qJ95twQTmdlpEkUtTt258mHnCV/pjMY9T0J7R1MDbYajkfhDQ1xIdKpVZEsYroEVv4jNOedbRHccF5XZLG7QcYGUk22A53XT0/zuyIBfQbYk/XShABdIHoNW+PNscrtahAmqqGmxkxQqZdI7DdB6V4f5J2YpLkt6k/nXvV1uA+Gm2uPylPvvJusVJJD0Z+BroyM4SsXFfaN9oAqGmNFMdIWR+17vl9TZmfN+K3KodMeiSTcVNUFKVAtMFXSaz80UzmKAB1D+EsZQrJ/Qzo4+OP52TwMmlLOBUY3TvgZkJrK+2MC5kGnwJlW3atjR8JlsKTdNJx/xoCg8HRbaqdxQAfz7zYBRnYfFeuf9Uvb0G7RW33CO0ifqP0gi9HUoQH3LxAiJ0zNqh+o=" + ) + ); + DOT_SKINS.add( + new Skin( + "eyJ0aW1lc3RhbXAiOjE0NTI0MTgzODM4OTUsInByb2ZpbGVJZCI6ImU4MjYwM2RmNDE3ZDRhOTViZDFmMTcyMDY0OGJlMGI0IiwicHJvZmlsZU5hbWUiOiJQYWJsZXRlMTIzNCIsInRleHR1cmVzIjp7IlNLSU4iOnsidXJsIjoiaHR0cDovL3RleHR1cmVzLm1pbmVjcmFmdC5uZXQvdGV4dHVyZS9lN2E3ZmY2M2RjZDU4NWM0YzZmNjM4OWI0ODZlMzBkNjg0MjE2NGZjNDRlOTQ2N2I4OWM0ZTFjZTZjMzg2OWY5In19fQ==", + "HMmoTUZECnTE/LoW4y4+yH7YENNOHqFdhYPFmULfFsEYjU/cY0eUu2LmlFcfjox0RTHqGebR0OmGnfVgim/p6n1RQtOXW0dt3GZKgrU10LPGRvEwQ6SMAB9/o5qKL+tnNDAtzbgrUJQh6kQGI7EU89h1KWeUpXmksPhnAPTvuXhFYEj467Ocg5Jz+CT1n8x4Gu0lXI8v8jHW+G/KP2JSQkLeLkqVRb8dGs9laFRvVwXQ3zLgTFgksgwGnuSlWTxoKVS//oLjwlZtiSowg1g+mQJJZxoH8esfAFGsxNKV+7JrdN13PfCkbdZYDpm5eom4SdrSflP3DXCBuGvBSFoStDYYegZEY5t7GhRizubZOU8ze3hfnbU8HqXZH4wqvmHzH7PhM6edQUrgJ+j9HV5jfpV9fQ9vhtlAFg9x1s9V8+yxpQ827FIqwyR4LY5cVZHyQCl1vkeCSuImrIUmYZ3ZsbQXzODDlzLEox++YDiEnUeuRCdJi4MInO9oKbZnZltEO4fsyWj7dRgQZQKWCR+iXaWiGsNmiiJiishn2+dEjFGg0L0pG6KE4XmkCJtDX2VvvgK3q4e9a0mZucZn68SjV3CcBghXkZ31pKzxxaQrKQoxs1KZFfG2UL7QDGmUURZxwWYzOo6KhI9eyAx41mujy8xlzarQzUErN4cwoFoPSmA=" + ) + ); + DOT_SKINS.add( + new Skin( + "eyJ0aW1lc3RhbXAiOjE0NTI0MTg0MDE0NzAsInByb2ZpbGVJZCI6ImU4MjYwM2RmNDE3ZDRhOTViZDFmMTcyMDY0OGJlMGI0IiwicHJvZmlsZU5hbWUiOiJQYWJsZXRlMTIzNCIsInRleHR1cmVzIjp7IlNLSU4iOnsidXJsIjoiaHR0cDovL3RleHR1cmVzLm1pbmVjcmFmdC5uZXQvdGV4dHVyZS8zYzY2ZDFmMDhkZmRmZTY2ZjljZDExYjA1MmY0YzM1YTdkMjk0MWZmMjNhOTRjY2UyM2Y3ZjgyMTg1NzcyZDgifX19", + "Rs2GuNrHjFBLk09ymZ/3UpTNSbbjmnZ3WvzA8n0X0gwzNHAx+8u/pNWO2uMEW1TZE5fhmrRAb8krfEpr/D5RdeXl+Se7NRch4mxpWqz4jiipMigFgGnf/s0JY+/dn5amGnoHKzqsktHFx3qwwOjGaz2jj1vhysuzQLGptnurn9wnRgVIueWfR2Cctc0v1pJ9jBVx/gkG3N+2Wznml+50pphxhcYBtfUKtwnMRxHIOz0me1KuRhqmBtmMzoQUArJXiz7cAX8cRlTqUg2ilY4UYLxNsH3cyaJi//tOzpk7EEwo2W1vYT/ZqiHTUvDBeRSu4Or9YZ7TwF/klbSnZJqaC2X0du00QcaoGAvFPY+A9HXZ3QII7k4g0M+aI3huiDUQX24O3p9h4J4dKJpktq1FH0G271uf5m3DMQlAQHTJWP07r3rL/23hAALMtIjE4SvUANd+WBxAeAlgSQamWk2YKQv/TxnNlr6tZMKOz/L1xsXJdn4eATWO786wH5IlxHKwgIQnmEYPSZX3AYsGtIsYuQhttbjmqYiecNdywXy6/WpZwhUHWW2aKuvkczJ8kX5Mcq+viVQRWRJNsCwqwzeXMLEX5tpNGOlQAyRJ/lyGUYJKmEXyqWXIxJstbJG09OR/G9V53ZhNa1hEaaVGv1FwZ9WdH1xHhGyJySz9JtrmKQ0=" + ) + ); + DOT_SKINS.add( + new Skin( + "eyJ0aW1lc3RhbXAiOjE0NTI0MTg0MjUyNTQsInByb2ZpbGVJZCI6ImU4MjYwM2RmNDE3ZDRhOTViZDFmMTcyMDY0OGJlMGI0IiwicHJvZmlsZU5hbWUiOiJQYWJsZXRlMTIzNCIsInRleHR1cmVzIjp7IlNLSU4iOnsidXJsIjoiaHR0cDovL3RleHR1cmVzLm1pbmVjcmFmdC5uZXQvdGV4dHVyZS9jMWViNWQ1MzExZjI1YjQ5MmEyMTIyYWM0YTNkYWUzZjNiMmRmNTc1NmFjYWM4ZjVjYjk2NWEyYjhjMGY4In19fQ==", + "LHeNKZWS3u7hmMmxqjEiCLAlhHRR4ZzQDZkCwJNid0odX38Qm98teyCwg4VmYKUrovIpqX3xReYiZ2LIY2SQDz6nARj6qarHQHDMgZ6Itqfd8jue5ZlzbwRwv9Fmirxdq67yA/VAMmy7Hel60X39PF/qVlVmA1k9nFz2NDmMlASA61nI2oEjfvdwRgODAG0rSkocIqxpZ8y/hUAsUsP2NPISIRl+yY+QLpzkx56+iTvLvYsYbhFMMJyjshjgL6j/TH9XRyjfqxfthTiKrH7zYSbxIb1nQC+Osrzg2EN9M2BPfyvF/MiFsQGu8It9CXSSR6ZFqTnDmhteFySiOrC8WF6F6rZL+vMYLSgke4vixLFLLdgdb1NBBMy8wGfEJFfLGs0n7UcnHERLg8ZTzz3yov6vKVd5dqv8uClQGHbv4iHVpvvepZ8BUuPH4PQgxqhs1akQ/q9B0RVXucigEcQMWfBAftGEDUI9PL17jjjsNbLYnX7yjSV3AWi3PPFVs7JWXrG+9KQPYHO1OuoA0ld3gA50+nSRXqcpDrvxRqo88MlqAv54Wc/I/lYOfpzx9BCgQsMz7n6wq22BsGLhNdbB+Usw/GB8s50KDZ91Zigc2REljgyoabzNBMHa/ACaPiBuFZ8ApBd84no+ipnpVJXnNcFxSH44AShuIcZaCdBlwbw=" + ) + ); + + } + + + public static Skin getDot(ChatColor color) { + return (DOT_SKINS.get(color.ordinal())); + } + + public static Skin getSkin(UUID uniqueId) { + if (CACHE.containsKey(uniqueId)) return CACHE.get(uniqueId); + + try { + URL url = new URL("https://sessionserver.mojang.com/session/minecraft/profile/" + uniqueId.toString().replace("-", "") + "?unsigned=false"); + JsonObject json = new JsonParser().parse(new InputStreamReader(url.openStream())).getAsJsonObject().get("properties").getAsJsonArray().get(0).getAsJsonObject(); + + return CACHE.put(uniqueId, new Skin(json.get("value").getAsString(), json.get("signature").getAsString())); + } catch (IOException ignored) { + // ignored + } + + return STEVE; + } + + public static Skin getSkin(Player player) { + return Tab.getInstance().getImplementation().getSkin(player); + } + +} diff --git a/src/main/java/dev/aapy/tablist/utils/CC.java b/src/main/java/dev/aapy/tablist/utils/CC.java new file mode 100644 index 0000000..8e42376 --- /dev/null +++ b/src/main/java/dev/aapy/tablist/utils/CC.java @@ -0,0 +1,67 @@ +package dev.aapy.tablist.utils; + +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +import java.lang.reflect.Field; +import java.util.List; +import java.util.stream.Collectors; + +public class CC { + + public static Enchantment FAKE_GLOW; + + public static String translate(String message) { + return ChatColor.translateAlternateColorCodes('&', message); + } + + public static List translate(List s) { + return s.stream().map(CC::translate).collect(Collectors.toList()); + } + + public static ItemStack nameItem(ItemStack item, String name, short durability, int amount, List lores) { + ItemMeta meta = item.getItemMeta(); + meta.setDisplayName(CC.translate(name)); + meta.setLore(CC.translate(lores)); + item.setItemMeta(meta); + item.setAmount(amount); + item.setDurability(durability); + return item; + } + + public static ItemStack nameItem(Material item, String name, short durability, int amount, List lores) { + return nameItem(new ItemStack(item), name, durability, amount, lores); + + } + + public static ItemStack enumItem(ItemStack item, short durability) { + item.setDurability(durability); + return item; + } + + public static ItemStack enumItem(Material item, short durability) { + return enumItem(new ItemStack(item), durability); + + } + + public static void registerFakeEnchantmentGlow() { + try { + Field f = Enchantment.class.getDeclaredField("acceptingNew"); + f.setAccessible(true); + f.set(null, true); + + Enchantment.registerEnchantment(FAKE_GLOW); + } catch (IllegalArgumentException e1) { + FAKE_GLOW = Enchantment.getById(70); + } catch (Exception e2) { + e2.printStackTrace(); + } + } + + static { + FAKE_GLOW = new FakeGlow(70); + } +} diff --git a/src/main/java/dev/aapy/tablist/utils/FakeGlow.java b/src/main/java/dev/aapy/tablist/utils/FakeGlow.java new file mode 100644 index 0000000..16bf1ee --- /dev/null +++ b/src/main/java/dev/aapy/tablist/utils/FakeGlow.java @@ -0,0 +1,43 @@ +package dev.aapy.tablist.utils; + +import org.bukkit.enchantments.Enchantment; +import org.bukkit.enchantments.EnchantmentTarget; +import org.bukkit.enchantments.EnchantmentWrapper; +import org.bukkit.inventory.ItemStack; + +public class FakeGlow extends EnchantmentWrapper { + + public FakeGlow(int id) { + super(id); + } + + @Override + public boolean canEnchantItem(ItemStack item) { + return true; + } + + @Override + public boolean conflictsWith(Enchantment item) { + return false; + } + + @Override + public EnchantmentTarget getItemTarget() { + return null; + } + + @Override + public String getName() { + return "FakeGlow"; + } + + @Override + public int getStartLevel() { + return 1; + } + + @Override + public int getMaxLevel() { + return 10; + } +} \ No newline at end of file diff --git a/src/main/java/dev/aapy/tablist/utils/LegacyClient.java b/src/main/java/dev/aapy/tablist/utils/LegacyClient.java new file mode 100644 index 0000000..d09f112 --- /dev/null +++ b/src/main/java/dev/aapy/tablist/utils/LegacyClient.java @@ -0,0 +1,34 @@ +package dev.aapy.tablist.utils; + +import org.bukkit.ChatColor; + +import java.util.ArrayList; + +public class LegacyClient { + + public static ArrayList ENTRY = getTabEntrys(); + public static ArrayList NAMES = getTeamNames(); + + private static ArrayList getTabEntrys() { + ArrayList list = new ArrayList<>(); + for (int i = 1; i <= 15; i++) { + String entry = ChatColor.values()[i].toString(); + list.add(ChatColor.RED + entry); + list.add(ChatColor.GREEN + entry); + list.add(ChatColor.DARK_RED + entry); + list.add(ChatColor.DARK_GREEN + entry); + list.add(ChatColor.BLUE + entry); + list.add(ChatColor.DARK_BLUE + entry); + } + return list; + } + + private static ArrayList getTeamNames() { + ArrayList list = new ArrayList<>(); + for (int i = 0; i < 80; i++) { + String s = (i < 10 ? "\\u00010" : "\\u0001") + i; + list.add(s); + } + return list; + } +} diff --git a/src/main/java/dev/aapy/tablist/utils/Reflection.java b/src/main/java/dev/aapy/tablist/utils/Reflection.java new file mode 100644 index 0000000..b3d7041 --- /dev/null +++ b/src/main/java/dev/aapy/tablist/utils/Reflection.java @@ -0,0 +1,14 @@ +package dev.aapy.tablist.utils; + + +import java.lang.reflect.Field; + +public class Reflection { + + public static Field setAccessibleAndGet(Class clazz, String fieldName) throws NoSuchFieldException { + Field field = clazz.getDeclaredField(fieldName); + field.setAccessible(true); + + return field; + } +} diff --git a/src/main/java/dev/aapy/util/ArmorCreator.java b/src/main/java/dev/aapy/util/ArmorCreator.java new file mode 100644 index 0000000..d9f7296 --- /dev/null +++ b/src/main/java/dev/aapy/util/ArmorCreator.java @@ -0,0 +1,204 @@ +package dev.aapy.util; + +import com.google.common.collect.Lists; +import lombok.AllArgsConstructor; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Color; +import org.bukkit.Material; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.inventory.meta.LeatherArmorMeta; +import org.bukkit.inventory.meta.PotionMeta; +import org.bukkit.inventory.meta.SkullMeta; +import org.bukkit.material.MaterialData; +import org.bukkit.potion.PotionEffect; + +import java.util.List; + +/** + * @author 7qv_ on 9/2/2022. + * @project SnakeHub + */ +@AllArgsConstructor +public class ArmorCreator { + + private ItemStack itemStack; + + public ArmorCreator(Material material) { + this(material, 1); + } + + public ArmorCreator(Material material, int amount) { + this(material, amount, (short) 0); + } + + public ArmorCreator(Material material, int amount, short damage) { + this(new ItemStack(material, amount, damage)); + } + + public ArmorCreator setColor(Color color) { + LeatherArmorMeta leatherArmorMeta = (LeatherArmorMeta) itemStack.getItemMeta(); + leatherArmorMeta.setColor(color); + itemStack.setItemMeta(leatherArmorMeta); + return this; + } + + public ArmorCreator setType(Material material) { + itemStack.setType(material); + return this; + } + + public ArmorCreator setAmount(int amount) { + itemStack.setAmount(amount); + return this; + } + + public ArmorCreator setDurability(int durability) { + itemStack.setDurability((short) durability); + return this; + } + + public ArmorCreator setData(int data) { + itemStack.setData(new MaterialData(data)); + return this; + } + + public ArmorCreator addEnchantment(Enchantment enchantment) { + addEnchantment(enchantment, 1); + return this; + } + + public ArmorCreator addEnchantment(Enchantment enchantment, int level) { + itemStack.addUnsafeEnchantment(enchantment, level); + return this; + } + + public ArmorCreator removeEnchantment(Enchantment enchantment) { + itemStack.removeEnchantment(enchantment); + return this; + } + + public ArmorCreator clearEnchantments() { + for (Enchantment enchantment : itemStack.getEnchantments().keySet()) + itemStack.removeEnchantment(enchantment); + + return this; + } + + public ArmorCreator setDisplayName(String name) { + ItemMeta itemMeta = itemStack.getItemMeta(); + itemMeta.setDisplayName(ChatColor.translateAlternateColorCodes('&', name)); + itemStack.setItemMeta(itemMeta); + return this; + } + + public ArmorCreator addLore(String lore) { + ItemMeta itemMeta = itemStack.getItemMeta(); + + List lores = itemMeta.getLore(); + if (lores == null) + lores = Lists.newArrayList(); + + lores.add(CC.translate(lore)); + + itemMeta.setLore(lores); + + itemStack.setItemMeta(itemMeta); + return this; + } + + public ArmorCreator setLore(String... lores) { + clearLore(); + + for (String lore : lores) + addLore(lore); + + return this; + } + + public ArmorCreator setLore(List lore) { + clearLore(); + + ItemMeta itemMeta = itemStack.getItemMeta(); + itemMeta.setLore(CC.translate(lore)); + itemStack.setItemMeta(itemMeta); + + return this; + } + + public ArmorCreator clearLore() { + ItemMeta itemMeta = itemStack.getItemMeta(); + itemMeta.setLore(Lists.newArrayList()); + itemStack.setItemMeta(itemMeta); + return this; + } + + public ArmorCreator setPotionEffect(PotionEffect effect) { + PotionMeta potionMeta = (PotionMeta) itemStack.getItemMeta(); + potionMeta.setMainEffect(effect.getType()); + potionMeta.addCustomEffect(effect, false); + itemStack.setItemMeta(potionMeta); + return this; + } + + public ItemStack build() { + ItemMeta itemMeta = itemStack.getItemMeta(); + final ItemStack clone = this.itemStack.clone(); + clone.setItemMeta(itemMeta.clone()); + return clone; + } + + public ArmorCreator setPotionEffects(PotionEffect... effects) { + PotionMeta potionMeta = (PotionMeta) itemStack.getItemMeta(); + potionMeta.setMainEffect(effects[0].getType()); + + for (PotionEffect effect : effects) + potionMeta.addCustomEffect(effect, false); + + itemStack.setItemMeta(potionMeta); + return this; + } + + public static Inventory createInventory(String title, int rows) { + Inventory inv = Bukkit.getServer().createInventory(null, rows * 9, CC.translate(title)); + return inv; + } + + public static ItemStack createItemStack(String name, List lore, Material material, int amount, int data) { + ItemStack item = new ItemStack(material, amount, (short) data); + ItemMeta itemmeta = item.getItemMeta(); + itemmeta.setDisplayName(CC.translate(name)); + itemmeta.setLore(CC.translateFromArray(lore)); + item.setItemMeta(itemmeta); + return item; + } + + public static ItemStack createItemStackWithoutLore(String name, Material material, int amount, int data) { + ItemStack item = new ItemStack(material, amount, (short) data); + ItemMeta itemmeta = item.getItemMeta(); + itemmeta.setDisplayName(CC.translate(name)); + item.setItemMeta(itemmeta); + return item; + } + + public ArmorCreator setSkullOwner(String owner) { + SkullMeta skullMeta = (SkullMeta) itemStack.getItemMeta(); + skullMeta.setOwner(owner); + + itemStack.setItemMeta(skullMeta); + return this; + } + + public ArmorCreator setName(final String displayName) { + ItemMeta itemMeta = itemStack.getItemMeta(); + itemMeta.setDisplayName(displayName); + return this; + } + + public ItemStack create() { + return itemStack; + } +} \ No newline at end of file diff --git a/src/main/java/dev/aapy/util/CC.java b/src/main/java/dev/aapy/util/CC.java new file mode 100644 index 0000000..123e422 --- /dev/null +++ b/src/main/java/dev/aapy/util/CC.java @@ -0,0 +1,119 @@ +package dev.aapy.util; + +import org.apache.commons.lang.StringEscapeUtils; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import java.util.ArrayList; +import java.util.List; + +/** + * @author 7qv_ on 7/2/2022. + * @project SnakeHub + */ +public class CC { + + public static final String BLUE = ChatColor.BLUE.toString(); + public static final String AQUA = ChatColor.RED.toString(); + public static final String YELLOW = ChatColor.GRAY.toString(); + public static final String RED = ChatColor.RED.toString(); + public static final String GRAY = ChatColor.GRAY.toString(); + public static final String GOLD = ChatColor.RED.toString(); + public static final String GREEN = ChatColor.GREEN.toString(); + public static final String WHITE = ChatColor.WHITE.toString(); + public static final String BLACK = ChatColor.BLACK.toString(); + public static final String BOLD = ChatColor.BOLD.toString(); + public static final String ITALIC = ChatColor.ITALIC.toString(); + public static final String UNDER_LINE = ChatColor.UNDERLINE.toString(); + public static final String STRIKE_THROUGH = ChatColor.STRIKETHROUGH.toString(); + public static final String RESET = ChatColor.RESET.toString(); + public static final String MAGIC = ChatColor.MAGIC.toString(); + public static final String DARK_BLUE = ChatColor.DARK_BLUE.toString(); + public static final String DARK_AQUA = ChatColor.DARK_AQUA.toString(); + public static final String DARK_GRAY = ChatColor.DARK_GRAY.toString(); + public static final String DARK_GREEN = ChatColor.DARK_GREEN.toString(); + public static final String DARK_PURPLE = ChatColor.DARK_PURPLE.toString(); + public static final String DARK_RED = ChatColor.DARK_RED.toString(); + public static final String PINK = ChatColor.LIGHT_PURPLE.toString(); + + + public static List translateFromArray(List text) { + List messages = new ArrayList(); + for (String string : text) { + messages.add(translateFromString(string)); + } + return messages; + } + + public static String translateFromString(String text) { + return StringEscapeUtils.unescapeJava(ChatColor.translateAlternateColorCodes('&', text)); + } + + /** + * The constant MENU_BAR. + */ + public static final String MENU_BAR = ChatColor.GRAY.toString() + ChatColor.STRIKETHROUGH.toString() + "------------------------"; + /** + * The constant CHAT_BAR. + */ + public static final String CHAT_BAR = ChatColor.GRAY.toString() + ChatColor.STRIKETHROUGH.toString() + "------------------------------------------------"; + /** + * The constant SB_BAR. + */ + public static final String SB_BAR = ChatColor.GRAY.toString() + ChatColor.STRIKETHROUGH.toString() + "----------------------"; + + /** + * Translate string. + * + * @param in the in + * @return the string + */ + public static String translate(String in) { + return ChatColor.translateAlternateColorCodes('&', in); + } + + public static void log(String in) { + Bukkit.getConsoleSender().sendMessage(translate(in)); + } + + /** + * Translate list. + * + * @param lines the lines + * @return the list + */ + public static List translate(List lines) { + List toReturn = new ArrayList<>(); + + for (String line : lines) { + toReturn.add(ChatColor.translateAlternateColorCodes('&', line)); + } + + return toReturn; + } + + /** + * Translate list. + * + * @param lines the lines + * @return the list + */ + public static List translate(String[] lines) { + List toReturn = new ArrayList<>(); + + for (String line : lines) { + if (line != null) { + toReturn.add(ChatColor.translateAlternateColorCodes('&', line)); + } + } + + return toReturn; + } + public static boolean isInteger(String value) { + try { + Integer.parseInt(value); + } catch (NumberFormatException e) { + return false; + } + return true; + } +} \ No newline at end of file diff --git a/src/main/java/dev/aapy/util/ItemCreator.java b/src/main/java/dev/aapy/util/ItemCreator.java new file mode 100644 index 0000000..d1b8c83 --- /dev/null +++ b/src/main/java/dev/aapy/util/ItemCreator.java @@ -0,0 +1,94 @@ +package dev.aapy.util; + +import org.bukkit.Color; +import org.bukkit.Material; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.inventory.meta.LeatherArmorMeta; + +import java.util.HashMap; +import java.util.List; + +/** + * @author 7qv_ on 18/2/2022. + * @project SnakeHub + */ +public class ItemCreator { + private Material material; + private Short durability; + private String title; + private int amount = 1; + private List lores; + @SuppressWarnings("unused") + private byte materialData; + private HashMap enchantments = new HashMap<>(); + private ItemStack itemStack; + + public ItemCreator() { + this.itemStack = new ItemStack(Material.AIR); + } + + public ItemCreator(Material material) { + this.itemStack = new ItemStack(material); + } + + public ItemCreator(ItemStack itemStack) { + this.itemStack = itemStack; + } + + public ItemCreator material(Material material){ + this.material = material; + return this; + } + + public ItemCreator durability(short durability){ + this.durability = durability; + return this; + } + + public ItemCreator title(String title){ + this.title = title; + return this; + } + + public ItemCreator amount(int amount){ + this.amount = amount; + return this; + } + + public ItemCreator lores(List lores){ + this.lores = lores; + return this; + } + public ItemStack build(){ + ItemStack itemStack = this.itemStack; + if (this.material != null) { + itemStack.setType(this.material); + } + //TODO Enchantments + for (Enchantment enchantment : enchantments.keySet()) { + itemStack.addUnsafeEnchantment(enchantment, enchantments.get(enchantment)); + } + ItemMeta meta = itemStack.getItemMeta(); + if (this.amount > 0) + itemStack.setAmount(this.amount); + if (this.durability != null) + itemStack.setDurability(this.durability); + if (this.title != null) + meta.setDisplayName(CC.translate("&r" + this.title)); + if (this.lores != null && this.lores.size() > 0) + meta.setLore(CC.translate(this.lores)); + itemStack.setItemMeta(meta); + return itemStack; + } + public ItemCreator color(Color color) { + ItemMeta meta = this.itemStack.getItemMeta(); + if (!(meta instanceof LeatherArmorMeta)) { + throw new UnsupportedOperationException("Cannot set color of a non-leather armor item."); + } + ((LeatherArmorMeta)meta).setColor(color); + this.itemStack.setItemMeta(meta); + return this; + } +} diff --git a/src/main/java/dev/aapy/util/ScoreFooterTask.java b/src/main/java/dev/aapy/util/ScoreFooterTask.java new file mode 100644 index 0000000..b3a19a5 --- /dev/null +++ b/src/main/java/dev/aapy/util/ScoreFooterTask.java @@ -0,0 +1,52 @@ +package dev.aapy.util; + +import dev.aapy.file.Scoreboard; +import org.bukkit.Bukkit; +import org.bukkit.scheduler.BukkitRunnable; + +/** + * @author 7qv_ on 11/2/2022. + * @project SnakeHub + */ +public class ScoreFooterTask extends BukkitRunnable { + + public static String footer = ""; + + private int left; + + public ScoreFooterTask() { + this.left = 3; + } + + @Deprecated + public void run() { + --this.left; + if (this.left < 0) { + this.left = 3; + this.sendFooter(); + } + if (Bukkit.getOnlinePlayers().size() < 0) { + this.cancel(); + } + + } + + public String sendFooter() { + String message = footer; + if (this.left <= 3) { + if (this.left < 4) { + message = Scoreboard.getConfig().getString("SCOREBOARD.ANIMATED.FOOTER.LINES.1"); + } + if (this.left < 3) { + message = Scoreboard.getConfig().getString("SCOREBOARD.ANIMATED.FOOTER.LINES.2"); + } + if (this.left < 2) { + message = Scoreboard.getConfig().getString("SCOREBOARD.ANIMATED.FOOTER.LINES.3"); + } + if (this.left < 1) { + message = Scoreboard.getConfig().getString("SCOREBOARD.ANIMATED.FOOTER.LINES.4"); + } + } + return message; + } +} \ No newline at end of file diff --git a/src/main/java/dev/aapy/util/ScoreTitleTask.java b/src/main/java/dev/aapy/util/ScoreTitleTask.java new file mode 100644 index 0000000..e217c67 --- /dev/null +++ b/src/main/java/dev/aapy/util/ScoreTitleTask.java @@ -0,0 +1,61 @@ +package dev.aapy.util; + +import dev.aapy.file.Scoreboard; +import org.bukkit.Bukkit; +import org.bukkit.scheduler.BukkitRunnable; + +/** + * @author 7qv_ on 16/2/2022. + * @project SnakeHub + */ +public class ScoreTitleTask extends BukkitRunnable { + + public static String title = ""; + + private int left; + + public ScoreTitleTask() { + this.left = 8; + } + + @Deprecated + public void run() { + --this.left; + if (this.left < 0) { + this.left = 8; + this.sendTitle(); + } + if (Bukkit.getOnlinePlayers().size() < 0) { + this.cancel(); + } + + } + + public String sendTitle() { + String message = title; + if (this.left <= 8) { + if (this.left < 7) { + message = Scoreboard.getConfig().getString("SCOREBOARD.ANIMATED.TITLE.LINES.1"); + } + if (this.left < 6) { + message = Scoreboard.getConfig().getString("SCOREBOARD.ANIMATED.TITLE.LINES.2"); + } + if (this.left < 5) { + message = Scoreboard.getConfig().getString("SCOREBOARD.ANIMATED.TITLE.LINES.3"); + } + if (this.left < 4) { + message = Scoreboard.getConfig().getString("SCOREBOARD.ANIMATED.TITLE.LINES.4"); + } + if (this.left < 3) { + message = Scoreboard.getConfig().getString("SCOREBOARD.ANIMATED.TITLE.LINES.5"); + } + if (this.left < 2) { + message = Scoreboard.getConfig().getString("SCOREBOARD.ANIMATED.TITLE.LINES.6"); + } + if (this.left < 1) { + message = Scoreboard.getConfig().getString("SCOREBOARD.ANIMATED.TITLE.LINES.7"); + } + } + return message; + } +} diff --git a/src/main/java/dev/aapy/util/SnakeUtil.java b/src/main/java/dev/aapy/util/SnakeUtil.java new file mode 100644 index 0000000..6465c84 --- /dev/null +++ b/src/main/java/dev/aapy/util/SnakeUtil.java @@ -0,0 +1,18 @@ +package dev.aapy.util; + +import java.text.SimpleDateFormat; +import java.util.Date; + +/** + * @author 7qv_ on 14/3/2022. + * @project SnakeHub + */ +public class SnakeUtil { + public static String getDate() { + return (new SimpleDateFormat("dd/MM/yyyy")).format(new Date()); + } + + public static String getHour() { + return (new SimpleDateFormat("HH:mm")).format(new Date()); + } +} diff --git a/src/main/java/dev/aapy/util/bungee/BungeeChannel.java b/src/main/java/dev/aapy/util/bungee/BungeeChannel.java new file mode 100644 index 0000000..24b5ede --- /dev/null +++ b/src/main/java/dev/aapy/util/bungee/BungeeChannel.java @@ -0,0 +1,21 @@ +package dev.aapy.util.bungee; + +import com.google.common.io.ByteArrayDataOutput; +import com.google.common.io.ByteStreams; +import dev.aapy.SnakeHub; +import org.bukkit.entity.Player; + +/** + * @author 7qv_ on 16/2/2022. + * @project SnakeHub + */ +public class BungeeChannel { + + public static void sendToServer(final Player player, final String server) { + final ByteArrayDataOutput out = ByteStreams.newDataOutput(); + out.writeUTF("Connect"); + out.writeUTF(server); + player.sendPluginMessage(SnakeHub.getInst(), "BungeeCord", out.toByteArray()); + } + +} \ No newline at end of file diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml new file mode 100644 index 0000000..386473d --- /dev/null +++ b/src/main/resources/config.yml @@ -0,0 +1,147 @@ +# ____ _ _ _ _ # +# / ___| _ __ __ _| | _____| | | |_ _| |__ # +# \___ \| "_ \ / _` | |/ / _ \ |_| | | | | "_ \ # +# ___) | | | | (_| | < __/ _ | |_| | |_) |# +# |____/|_| |_|\__,_|_|\_\___|_| |_|\__,_|_.__/ # +################################################# + +# BOOLEANS CONFIG + +BOOLEANS: + JOIN-MESSAGE: false + QUIT-MESSAGE: false + TABLIST: false + LUNAR-CLIENT: + NAMETAG: false + SCOREBOARD: + ANIMATED: + FOOTER: true + TITLE: false + +CHAT-FORMAT: + - "{prefix}{player}&7: &f{message}" + +LAUNCH-PAD: + MATERIAL: GOLD_PLATE + SOUND: EXPLODE + +SOCIAL: + DISCORD: discord.gg/InfernalMC + STORE: store.infernalmc.cc + TEAMSPEAK: ts.infernalmc.cc + TWITTER: twitter.com/InfernalMC_ + WEBSITE: www.infernalmc.cc + +SELECTOR: + ENABLED: true + MATERIAL: WATCH + ENCHANTED: false + SOUND_ENABLED: false + SOUND: CHEST_OPEN + GLASS_PANEL: + ENABLED: false + ID: 14 + DISPLAYNAME: "&4\u2726 &4Server Selector &4\u2726" + TITLE: "&8Select A Server" + SLOT: 4 + LORE: "&7Right-click to open the hub menu!" + SERVERS: + "1": + DISPLAYNAME: "&e&lDEV &4Kits" + MATERIAL: GOLDEN_APPLE + ENCHANTED: false + SLOT: 11 + MESSAGE: "&aSent you to the server Kitmap!" + BUNGEE: + ENABLED: false + SERVER: KITMAP + EZQUEUE: + ENABLED: true + QUEUE: PRACTICE + LORE: + - "&7Battle other users in a shot-" + - "&7paced environment. Build your" + - "&7base and practice classes." + - "" + - "&6Players: &f%bungee_kitmap%" + - "&6Status: &f%aqua_server_status_Kits%" + - "" + - "&7&oClick to join the queue." + "2": + DISPLAYNAME: "&4HCF" + MATERIAL: DIAMOND_PICKAXE + ENCHANTED: false + SLOT: 15 + MESSAGE: "&aSent you to the server HCF!" + BUNGEE: + ENABLED: false + SERVER: HCF + EZQUEUE: + ENABLED: true + QUEUE: Leagues + LORE: + - "&7Create your team and grind" + - "&7to become the most powerful" + - "&7faction on the server." + - "" + - "&6Map Kit: &fUndefined" + - "&6Faction Size: &fUndefined" + - "" + - "&6Players: &f%bungee_Leagues%" + - "&6Status: &f%aqua_server_status_Leagues%" + - "" + - "&7&oClick to join the queue." + "3": + DISPLAYNAME: "&4???" + MATERIAL: REDSTONE_BLOCK + ENCHANTED: false + SLOT: 13 + MESSAGE: "&C???" + BUNGEE: + ENABLED: false + SERVER: PRACTICE + EZQUEUE: + ENABLED: true + QUEUE: PRACTICE + LORE: + - "&C???" +PVP: + ENABLED: false + MATERIAL: DIAMOND_SWORD + ENCHANTED: true + SOUND: CHEST_OPEN + DISPLAYNAME: "&4\u2726 &4PvP Mode &4\u2726" + SLOT: 6 + LORE: "&7Right-click to join to PvP Mode!" + +COSMETIC: + ENABLED: false + MATERIAL: EMERALD + ENCHANTED: false + GLASS_PANEL: + ENABLED: true + ID: 3 + DISPLAYNAME: "&4\u2726 &4Cosmetics &4\u2726" + SLOT: 6 + LORE: "&7Right-click to open the cosmetics menu!" + +ENDERBUTT: + ENABLED: true + MATERIAL: ENDER_PEARL + ENCHANTED: false + SOUND: PORTAL + DISPLAYNAME: "&4\u2726 &4EnderButt &4\u2726" + SLOT: 2 + LORE: "&7Right-Click For Fly" + +INVISIBILITY: + ENABLED: true + ITEM: + SHOW-PLAYER: + NAME: "&4\u2726 &aShow Players &4\u2726" + MATERIAL: BLAZE_ROD + SLOT: 6 + HIDE-PLAYER: + NAME: "&4\u2726 &7Hide Players &4\u2726" + MATERIAL: CLAY_BALL + SLOT: 6 \ No newline at end of file diff --git a/src/main/resources/lang.yml b/src/main/resources/lang.yml new file mode 100644 index 0000000..579f704 --- /dev/null +++ b/src/main/resources/lang.yml @@ -0,0 +1,46 @@ +# GENERAL LANG CONFIG + +JOIN: + MESSAGE: + - "&7&m-----*----------------------------------*-----" + - "&fBienvenido &c&l{ign} &fHubCore creada por &c&l7qv_" + - "" + - " &7\u25CF &fTu rango actual es: {rank}" + - " &7\u25CF &c&lStore: &f{store}" + - " &7\u25CF &c&lTeamspeak: &f{team-speak}" + - " &7\u25CF &c&lTwitter: &f{twitter}" + - " &7\u25CF &c&lDiscord: &f{discord}" + - " &7\u25CF &c&lWebsite: &f{web-site}" + - "&7&m-----*---------------------------------*-----" + +TITLE: #ONLY FOR LUNAR CLIENT API COMPATIBILITY WITH PLACEHOLDERAPI + ENABLED: true + JOIN: + TITLE: + MESSAGE: "&c&lInfernalMC Network" + SUBTITLE: + MESSAGE: "&fThanks For Playing" + +QUIT: + MESSAGE: + - "&7&m-----*----------------------------------*-----" + - "" + - "{rank} &c&l{ign} &fse desconecto" + - "" + - "&7&m-----*---------------------------------*-----" + + +HIDE-PLAYER: "&cPlayer visibility has been &cdisable&c." +SHOW-PLAYER: "&cPlayer visibility has been &aenable&c." + +SOCIAL: + DISCORD: + - "&cDiscord&7: &f{discord}" + STORE: + - "&cStore&7: &f{store}" + TEAMSPEAK: + - "&cTeamSpeak&7: &f{team-speak}" + TWITTER: + - "&cTwitter&7: &f{twitter}" + WEBSITE: + - "&cWebSite&7: &f{website}" \ No newline at end of file diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml new file mode 100644 index 0000000..7b00511 --- /dev/null +++ b/src/main/resources/plugin.yml @@ -0,0 +1,4 @@ +name: SnakeHub +version: 1.2.0-HOTFIX +main: dev.aapy.SnakeHub +authors: [Aapy] \ No newline at end of file diff --git a/src/main/resources/scoreboard.yml b/src/main/resources/scoreboard.yml new file mode 100644 index 0000000..18882e1 --- /dev/null +++ b/src/main/resources/scoreboard.yml @@ -0,0 +1,29 @@ +SCOREBOARD: + TITLE: "&c&lInfernalMC &f\u2503 &7Hub" + FOOTER: "&7ts.infernalmc.cc" + LINES: + - "&7&m--------------------" + - "&8{placeholder:date} &7&o{placeholder:time}" + - " " + - "&cOnline&7: {players_online}" + - "" + - "&cRank&7: {rank}" + - " " + - "{footers}" + - "&7&m--------------------" + ANIMATED: + FOOTER: + LINES: + 1: "&7discord.gg/InfernalMC" + 2: "&7twitter.com/InfernalMC_" + 3: "&7ts.infernalmc.cc" + 4: "&7store.infernalmc.cc" + TITLE: + LINES: + 1: "&cI" + 2: "&cIn" + 3: "&cInf" + 4: "&cInfe" + 5: "&cInfer" + 6: "&cInferna" + 7: "&cInfernalMC" \ No newline at end of file diff --git a/src/main/resources/tab.yml b/src/main/resources/tab.yml new file mode 100644 index 0000000..199bbd4 --- /dev/null +++ b/src/main/resources/tab.yml @@ -0,0 +1,254 @@ +TAB: + ENABLED: true + HEADER: + - "&c&lInfernalMC &lNetwork" + + FOOTER: + - "&fYou are playing &cHub-01 &fon &cinfernalmc.cc" + + LEFT: + 1: + TEXT: "" + SKIN: "" + 2: + TEXT: "" + SKIN: "" + 3: + TEXT: "" + SKIN: "" + 4: + TEXT: "&c&lStore" + SKIN: "{store}" + 5: + TEXT: "&fstore.infernalmc.cc" + SKIN: "" + 6: + TEXT: "" + SKIN: "" + 7: + TEXT: "" + SKIN: "" + 8: + TEXT: "" + SKIN: "" + 9: + TEXT: "&cKitmap&f: %pinger_players_localhost:25561%" + SKIN: "{enderchest}" + 10: + TEXT: "&fStatus: %pinger_isonline_localhost:25561%" + SKIN: "" + 11: + TEXT: "&eUnder Maintenance" + SKIN: "" + 12: + TEXT: "" + SKIN: "" + 13: + TEXT: "" + SKIN: "" + 14: + TEXT: "" + SKIN: "" + 15: + TEXT: "" + SKIN: "" + 16: + TEXT: "" + SKIN: "" + 17: + TEXT: "" + SKIN: "" + 18: + TEXT: "" + SKIN: "" + 19: + TEXT: "" + SKIN: "" + 20: + TEXT: "" + SKIN: "" + CENTER: + 1: + TEXT: "&c&lInfernalMC" + SKIN: "{planet}" + 2: + TEXT: "&cOnline&f: {players_online}/{players_max_online}" + SKIN: "" + 3: + TEXT: "" + SKIN: "" + 4: + TEXT: "" + SKIN: "" + 5: + TEXT: "" + SKIN: "" + 6: + TEXT: "" + SKIN: "" + 7: + TEXT: "&c&lServer &lInfo" + SKIN: "" + 8: + TEXT: "" + SKIN: "" + 9: + TEXT: "&cHCF&f: %pinger_players_localhost:25567%" + SKIN: "{castle}" + 10: + TEXT: "&fStatus: %pinger_isonline_localhost:25567%" + SKIN: "" + 11: + TEXT: "&fKit: Prot I, Sharp I" + SKIN: "" + 12: + TEXT: "" + SKIN: "" + 13: + TEXT: "" + SKIN: "" + 14: + TEXT: "" + SKIN: "" + 15: + TEXT: "" + SKIN: "" + 16: + TEXT: "" + SKIN: "" + 17: + TEXT: "" + SKIN: "" + 18: + TEXT: "" + SKIN: "" + 19: + TEXT: "" + SKIN: "" + 20: + TEXT: "" + SKIN: "" + RIGHT: + 1: + TEXT: "" + SKIN: "" + 2: + TEXT: "" + SKIN: "" + 3: + TEXT: "" + SKIN: "" + 4: + TEXT: "&c&lDiscord" + SKIN: "{discord}" + 5: + TEXT: "discord.gg/InfernalMC" + SKIN: "" + 6: + TEXT: "" + SKIN: "" + 7: + TEXT: "" + SKIN: "" + 8: + TEXT: "" + SKIN: "" + 9: + TEXT: "&cPractice&f: %pinger_players_localhost:25527%" + SKIN: "{heart}" + 10: + TEXT: "&fStatus: %pinger_isonline_localhost:25562%" + SKIN: "" + 11: + TEXT: "&eUnder Maintenance" + SKIN: "" + 12: + TEXT: "" + SKIN: "" + 13: + TEXT: "" + SKIN: "" + 14: + TEXT: "" + SKIN: "" + 15: + TEXT: "" + SKIN: "" + 16: + TEXT: "" + SKIN: "" + 17: + TEXT: "" + SKIN: "" + 18: + TEXT: "" + SKIN: "" + 19: + TEXT: "" + SKIN: "" + 20: + TEXT: "" + SKIN: "" + + # Only 1.8 # + farright: + 1: + TEXT: "" + SKIN: "" + 2: + TEXT: "" + SKIN: "" + 3: + TEXT: "" + SKIN: "" + 4: + TEXT: "" + SKIN: "" + 5: + TEXT: "" + SKIN: "" + 6: + TEXT: "" + SKIN: "" + 7: + TEXT: "" + SKIN: "" + 8: + TEXT: "" + SKIN: "" + 9: + TEXT: "" + SKIN: "" + 10: + TEXT: "" + SKIN: "" + 11: + TEXT: "" + SKIN: "" + 12: + TEXT: "" + SKIN: "" + 13: + TEXT: "" + SKIN: "" + 14: + TEXT: "" + SKIN: "" + 15: + TEXT: "" + SKIN: "" + 16: + TEXT: "" + SKIN: "" + 17: + TEXT: "" + SKIN: "" + 18: + TEXT: "" + SKIN: "" + 19: + TEXT: "" + SKIN: "" + 20: + TEXT: "" + SKIN: "" \ No newline at end of file