From 3928c0ae9e3ee1d328e6b1f3c2a094bc9dbd9979 Mon Sep 17 00:00:00 2001 From: Lorenzo Date: Thu, 9 Apr 2020 18:23:36 +0200 Subject: [PATCH] initial commit --- .idea/ant.xml | 9 + ...bugger__Listener__CommandExecutor__jar.xml | 8 + .idea/description.html | 0 .idea/dictionaries/Lorenzo.xml | 10 + .idea/encodings.xml | 6 + .idea/misc.xml | 6 + .idea/modules.xml | 8 + .idea/project-template.xml | 3 + .idea/template-meta.xml | 5 + .idea/uiDesigner.xml | 124 ++++++++ .idea/workspace.xml | 77 +++++ UHC-Core.iml | 31 ++ ant_build_increment.xml | 38 +++ ant_buildversion_end.txt | 1 + ant_buildversion_init.txt | 1 + build.number | 5 + src/config.yml | 40 +++ src/lang.yml | 5 + .../mindoverflow/network/uhccore/UhcCore.java | 99 ++++++ .../uhccore/commands/UhcCoreCommand.java | 109 +++++++ .../commands/uhccommands/HelpCommand.java | 13 + .../commands/uhccommands/ListCommand.java | 61 ++++ .../commands/uhccommands/ReloadCommand.java | 22 ++ .../uhccommands/SetFireworkCommand.java | 49 +++ .../commands/uhccommands/SetSpawnCommand.java | 32 ++ .../commands/uhccommands/StartUhcCommand.java | 133 ++++++++ .../uhccore/completers/InfoCompleter.java | 49 +++ .../uhccore/listeners/PlayerChatListener.java | 51 ++++ .../listeners/PlayerDeathRespawnListener.java | 253 +++++++++++++++ .../uhccore/listeners/PlayerHitListener.java | 43 +++ .../listeners/PlayerInteractListener.java | 119 ++++++++ .../uhccore/listeners/PlayerJoinListener.java | 37 +++ .../uhccore/listeners/PlayerMoveListener.java | 32 ++ .../uhccore/listeners/TeamsSelectorGUI.java | 53 ++++ .../network/uhccore/utils/CommonValues.java | 123 ++++++++ .../network/uhccore/utils/ConfigEntries.java | 36 +++ .../network/uhccore/utils/Debugger.java | 87 ++++++ .../network/uhccore/utils/FileUtils.java | 287 ++++++++++++++++++ .../uhccore/utils/LocalizedMessages.java | 18 ++ .../network/uhccore/utils/MessageUtils.java | 109 +++++++ .../uhccore/utils/PermissionUtils.java | 31 ++ .../network/uhccore/utils/Permissions.java | 10 + src/plugin.yml | 9 + 43 files changed, 2242 insertions(+) create mode 100644 .idea/ant.xml create mode 100644 .idea/artifacts/Spigot_Complete_Plugin__Debugger__Listener__CommandExecutor__jar.xml create mode 100644 .idea/description.html create mode 100644 .idea/dictionaries/Lorenzo.xml create mode 100644 .idea/encodings.xml create mode 100644 .idea/misc.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/project-template.xml create mode 100644 .idea/template-meta.xml create mode 100644 .idea/uiDesigner.xml create mode 100644 .idea/workspace.xml create mode 100644 UHC-Core.iml create mode 100644 ant_build_increment.xml create mode 100644 ant_buildversion_end.txt create mode 100644 ant_buildversion_init.txt create mode 100644 build.number create mode 100644 src/config.yml create mode 100644 src/lang.yml create mode 100644 src/net/mindoverflow/network/uhccore/UhcCore.java create mode 100644 src/net/mindoverflow/network/uhccore/commands/UhcCoreCommand.java create mode 100644 src/net/mindoverflow/network/uhccore/commands/uhccommands/HelpCommand.java create mode 100644 src/net/mindoverflow/network/uhccore/commands/uhccommands/ListCommand.java create mode 100644 src/net/mindoverflow/network/uhccore/commands/uhccommands/ReloadCommand.java create mode 100644 src/net/mindoverflow/network/uhccore/commands/uhccommands/SetFireworkCommand.java create mode 100644 src/net/mindoverflow/network/uhccore/commands/uhccommands/SetSpawnCommand.java create mode 100644 src/net/mindoverflow/network/uhccore/commands/uhccommands/StartUhcCommand.java create mode 100644 src/net/mindoverflow/network/uhccore/completers/InfoCompleter.java create mode 100644 src/net/mindoverflow/network/uhccore/listeners/PlayerChatListener.java create mode 100644 src/net/mindoverflow/network/uhccore/listeners/PlayerDeathRespawnListener.java create mode 100644 src/net/mindoverflow/network/uhccore/listeners/PlayerHitListener.java create mode 100644 src/net/mindoverflow/network/uhccore/listeners/PlayerInteractListener.java create mode 100644 src/net/mindoverflow/network/uhccore/listeners/PlayerJoinListener.java create mode 100644 src/net/mindoverflow/network/uhccore/listeners/PlayerMoveListener.java create mode 100644 src/net/mindoverflow/network/uhccore/listeners/TeamsSelectorGUI.java create mode 100644 src/net/mindoverflow/network/uhccore/utils/CommonValues.java create mode 100644 src/net/mindoverflow/network/uhccore/utils/ConfigEntries.java create mode 100644 src/net/mindoverflow/network/uhccore/utils/Debugger.java create mode 100644 src/net/mindoverflow/network/uhccore/utils/FileUtils.java create mode 100644 src/net/mindoverflow/network/uhccore/utils/LocalizedMessages.java create mode 100644 src/net/mindoverflow/network/uhccore/utils/MessageUtils.java create mode 100644 src/net/mindoverflow/network/uhccore/utils/PermissionUtils.java create mode 100644 src/net/mindoverflow/network/uhccore/utils/Permissions.java create mode 100644 src/plugin.yml diff --git a/.idea/ant.xml b/.idea/ant.xml new file mode 100644 index 0000000..43910fc --- /dev/null +++ b/.idea/ant.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/artifacts/Spigot_Complete_Plugin__Debugger__Listener__CommandExecutor__jar.xml b/.idea/artifacts/Spigot_Complete_Plugin__Debugger__Listener__CommandExecutor__jar.xml new file mode 100644 index 0000000..6312bfe --- /dev/null +++ b/.idea/artifacts/Spigot_Complete_Plugin__Debugger__Listener__CommandExecutor__jar.xml @@ -0,0 +1,8 @@ + + + D:/Coding/# Server per Test Plugins #/plugins + + + + + \ No newline at end of file diff --git a/.idea/description.html b/.idea/description.html new file mode 100644 index 0000000..e69de29 diff --git a/.idea/dictionaries/Lorenzo.xml b/.idea/dictionaries/Lorenzo.xml new file mode 100644 index 0000000..7ee5073 --- /dev/null +++ b/.idea/dictionaries/Lorenzo.xml @@ -0,0 +1,10 @@ + + + + bukkit + bungeecord + textcomponent + yamls + + + \ No newline at end of file diff --git a/.idea/encodings.xml b/.idea/encodings.xml new file mode 100644 index 0000000..97626ba --- /dev/null +++ b/.idea/encodings.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..0548357 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..301190e --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/project-template.xml b/.idea/project-template.xml new file mode 100644 index 0000000..3c6194b --- /dev/null +++ b/.idea/project-template.xml @@ -0,0 +1,3 @@ + \ No newline at end of file diff --git a/.idea/template-meta.xml b/.idea/template-meta.xml new file mode 100644 index 0000000..7089c7e --- /dev/null +++ b/.idea/template-meta.xml @@ -0,0 +1,5 @@ + \ No newline at end of file diff --git a/.idea/uiDesigner.xml b/.idea/uiDesigner.xml new file mode 100644 index 0000000..e96534f --- /dev/null +++ b/.idea/uiDesigner.xml @@ -0,0 +1,124 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/workspace.xml b/.idea/workspace.xml new file mode 100644 index 0000000..9fab3d0 --- /dev/null +++ b/.idea/workspace.xml @@ -0,0 +1,77 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1582211391295 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/UHC-Core.iml b/UHC-Core.iml new file mode 100644 index 0000000..43c5e7f --- /dev/null +++ b/UHC-Core.iml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ant_build_increment.xml b/ant_build_increment.xml new file mode 100644 index 0000000..e1f09fc --- /dev/null +++ b/ant_build_increment.xml @@ -0,0 +1,38 @@ + + + simple example increment build variable + + + + + + + + + + Changing build version from BUILD_VERSION to ${version}.${build.number} in file plugin.yml... + + + Changed! + + + + + + Changing back build version ${version}.${build.number} in file plugin.yml to BUILD_VERSION... + + + + + Changed! + + + \ No newline at end of file diff --git a/ant_buildversion_end.txt b/ant_buildversion_end.txt new file mode 100644 index 0000000..52cbf58 --- /dev/null +++ b/ant_buildversion_end.txt @@ -0,0 +1 @@ +Changing back build version 0.0.135 in file plugin.yml to BUILD_VERSION... \ No newline at end of file diff --git a/ant_buildversion_init.txt b/ant_buildversion_init.txt new file mode 100644 index 0000000..a290bc0 --- /dev/null +++ b/ant_buildversion_init.txt @@ -0,0 +1 @@ +Changed! \ No newline at end of file diff --git a/build.number b/build.number new file mode 100644 index 0000000..77e5172 --- /dev/null +++ b/build.number @@ -0,0 +1,5 @@ +#Build Number for ANT. Do not edit! +#Tue Feb 25 14:58:59 CET 2020 +\#Build=Number for ANT. Do not edit\! +build.number=136 +\#Tue=Jul 30 16\:09\:09 CEST 2019 diff --git a/src/config.yml b/src/config.yml new file mode 100644 index 0000000..ef95f7f --- /dev/null +++ b/src/config.yml @@ -0,0 +1,40 @@ +settings: + uhcworlds: ['world', 'world_nether'] + lobbyworlds: ['flat'] + teams: 4 + friendly-fire: false + border: + center-x: 0 + center-z: 0 + size: 4000 +spawn: + world: __UNSET__ + x: 0.0 + y: 0.0 + z: 0.0 + yaw: 0.0 + pitch: 0.0 +firework-pos: + 1: + world: __UNSET__ + x: 0.0 + y: 0.0 + z: 0.0 +teams: + - '§9Blue' + - '§cRed' + - '§aGreen' + - '§eYellow' + - '§5Purple' + - '§6Orange' + - '§8Black' + - '§dPink' +team-items: + - 'BLUE_WOOL' + - 'RED_WOOL' + - 'LIME_WOOL' + - 'YELLOW_WOOL' + - 'PURPLE_WOOL' + - 'ORANGE_WOOL' + - 'BLACK_WOOL' + - 'PINK_WOOL' \ No newline at end of file diff --git a/src/lang.yml b/src/lang.yml new file mode 100644 index 0000000..3eeeabe --- /dev/null +++ b/src/lang.yml @@ -0,0 +1,5 @@ +error: + console_access: '&eWarning! You are accessing the plugin command from console.' + console_access_blocked: '&cSorry, but this command is not available via console.' +info: '&bThis is a colored and localized message!' +player_position: '&bYour position is: &e%pos%' \ No newline at end of file diff --git a/src/net/mindoverflow/network/uhccore/UhcCore.java b/src/net/mindoverflow/network/uhccore/UhcCore.java new file mode 100644 index 0000000..fefe385 --- /dev/null +++ b/src/net/mindoverflow/network/uhccore/UhcCore.java @@ -0,0 +1,99 @@ +package net.mindoverflow.network.uhccore; + +import net.mindoverflow.network.uhccore.commands.UhcCoreCommand; +import net.mindoverflow.network.uhccore.completers.InfoCompleter; +import net.mindoverflow.network.uhccore.listeners.*; +import net.mindoverflow.network.uhccore.utils.Debugger; +import net.mindoverflow.network.uhccore.utils.FileUtils; +import net.mindoverflow.network.uhccore.utils.MessageUtils; +import org.bukkit.plugin.PluginManager; +import org.bukkit.plugin.java.JavaPlugin; + +import java.util.logging.Level; +import java.util.logging.Logger; + +public class UhcCore extends JavaPlugin +{ + // Instantiate a Debugger for this class. + private Debugger debugger = new Debugger(getClass().getName()); + + // Initializing needed variables. + public static Logger logger; + private PluginManager pluginManager; + + // Method called when the plugin is being loaded. + @Override + public void onEnable() + { + + // We need to run this in a task, because the plugin has to be initialized AFTER all the worlds are loaded. + getServer().getScheduler().runTask(this, ()-> + { + + // Give the initialized variables their respective values. Absolutely don't do this before as they will look good in the IDE but will result null. + logger = getLogger(); + pluginManager = getServer().getPluginManager(); + + // Check and report if the Debugger is enabled (the method itself does the checking). Would do it before but we need the logger to be initialized! :( + debugger.sendDebugMessage(Level.WARNING, "---[ DEBUGGER IS ENABLED! ]---"); + debugger.sendDebugMessage(Level.WARNING, "---[ INITIALIZING PLUGIN ]---"); + debugger.sendDebugMessage(Level.INFO, "Logger and PluginManager already initialized."); + + // Register instances and give them the plugin parameter (this, because this class is the JavaPlugin) so they can access all of its info. + debugger.sendDebugMessage(Level.INFO, "Instantiating some classes that need to access to plugin data..."); + FileUtils fileUtilsInstance = new FileUtils(this); + UhcCoreCommand uhcCoreCommandInstance = new UhcCoreCommand(this); + MessageUtils messageUtilsInstance = new MessageUtils(this); + PlayerChatListener playerChatListenerInstance = new PlayerChatListener(this); + PlayerDeathRespawnListener playerDeathRespawnListenerInstance = new PlayerDeathRespawnListener(this); + PlayerMoveListener playerMoveListenerInstance = new PlayerMoveListener(this); + debugger.sendDebugMessage(Level.INFO, "Done instantiating classes!"); + + + // Check if all needed files exist and work correctly, also loading their YAMLs. + debugger.sendDebugMessage(Level.INFO, "Checking files..."); + FileUtils.checkFiles(); + debugger.sendDebugMessage(Level.INFO, "Done checking files!"); + + /* + Load all the YAML files. We are already loading them in FileUtils's checkFiles() method but we are loading them singularly. + With this method we are sure that all the files get successfully loaded. Better twice than never... + */ + debugger.sendDebugMessage(Level.INFO, "Reloading YAML config..."); + FileUtils.reloadYamls(); + debugger.sendDebugMessage(Level.INFO, "Done!"); + + // Register Listeners + debugger.sendDebugMessage(Level.INFO, "Registering listeners..."); + pluginManager.registerEvents(new PlayerJoinListener(), this); + pluginManager.registerEvents(playerDeathRespawnListenerInstance, this); + pluginManager.registerEvents(new PlayerInteractListener(), this); + pluginManager.registerEvents(playerChatListenerInstance, this); + pluginManager.registerEvents(new PlayerHitListener(), this); + pluginManager.registerEvents(playerMoveListenerInstance, this); + debugger.sendDebugMessage(Level.INFO, "Done registering listeners!"); + + // Register Commands + debugger.sendDebugMessage(Level.INFO, "Registering commands..."); + getCommand("uhc").setExecutor(uhcCoreCommandInstance); + getCommand("uhc").setTabCompleter(new InfoCompleter()); + debugger.sendDebugMessage(Level.INFO, "Done registering commands!"); + + // Send success output message to console. + logger.log(Level.INFO, "Plugin " + getDescription().getName() + " Successfully Loaded!"); + debugger.sendDebugMessage(Level.WARNING, "---[ INITIALIZATION DONE ]---"); + }); + + } + + // Method called when the plugin is being unloaded. + @Override + public void onDisable() { + debugger.sendDebugMessage(Level.WARNING, "---[ DEBUGGER IS ENABLED! ]---"); + debugger.sendDebugMessage(Level.WARNING, "---[ DISABLING PLUGIN ]---"); + logger.log(Level.INFO, "Plugin " + getDescription().getName() + " Successfully Unloaded!"); + debugger.sendDebugMessage(Level.WARNING, "---[ PLUGIN DISABLED ]---"); + } + + +} \ No newline at end of file diff --git a/src/net/mindoverflow/network/uhccore/commands/UhcCoreCommand.java b/src/net/mindoverflow/network/uhccore/commands/UhcCoreCommand.java new file mode 100644 index 0000000..16b10d4 --- /dev/null +++ b/src/net/mindoverflow/network/uhccore/commands/UhcCoreCommand.java @@ -0,0 +1,109 @@ +package net.mindoverflow.network.uhccore.commands; + +import net.mindoverflow.network.uhccore.UhcCore; +import net.mindoverflow.network.uhccore.commands.uhccommands.*; +import net.mindoverflow.network.uhccore.utils.Debugger; +import net.mindoverflow.network.uhccore.utils.MessageUtils; +import net.mindoverflow.network.uhccore.utils.LocalizedMessages; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.command.ConsoleCommandSender; +import org.bukkit.entity.Player; + +import java.util.logging.Level; + +public class UhcCoreCommand implements CommandExecutor +{ + + // Initialize the plugin variable so we can access all of the plugin's data. + private UhcCore plugin; + + // Initialize the debugger so I can debug the plugin. + private Debugger debugger = new Debugger(getClass().getName()); + + // Constructor to actually give "plugin" a value. + public UhcCoreCommand(UhcCore givenPlugin) + { + plugin = givenPlugin; + } + + + + // Override the default command. Set the instructions for this particular command (registered in the main class). + @Override + public boolean onCommand(CommandSender commandSender, Command command, String s, String[] args) + { + // Log who is using the command. + debugger.sendDebugMessage(Level.INFO, "Sender is instance of: " + commandSender.getClass().getName()); + + // If the command comes from Console, give a warning. + boolean senderIsConsole = (commandSender instanceof ConsoleCommandSender); + if(senderIsConsole) + { + MessageUtils.sendLocalizedMessage(commandSender.getName(), LocalizedMessages.WARNING_CONSOLE_ACCESS); + // Only uncomment the following line if the command should not be able to run this command. + } + + // Check if there are any args. + if(args.length == 0 || args[0].equalsIgnoreCase("help")) + { + HelpCommand.infoCommand(commandSender, plugin); + } + // Check if there is a single argument after the command itself. + else if (args.length == 1) + { + // Check if the args are "reload" and in case, do it. + if(args[0].equalsIgnoreCase("reload")) + { + ReloadCommand.reloadCommand(commandSender); + } + else if(args[0].equalsIgnoreCase("setspawn")) + { + if(!(commandSender instanceof Player)) + { + MessageUtils.sendLocalizedMessage(commandSender.getName(), LocalizedMessages.ERROR_CONSOLE_ACCESS_BLOCKED); + } + else + { + SetSpawnCommand.setSpawn(commandSender); + } + } + else if(args[0].equalsIgnoreCase("setfirework")) + { + if(!(commandSender instanceof Player)) + { + MessageUtils.sendLocalizedMessage(commandSender.getName(), LocalizedMessages.ERROR_CONSOLE_ACCESS_BLOCKED); + } + else + { + SetFireworkCommand.setFireworkCommand(commandSender); + } + } + else if(args[0].equalsIgnoreCase("list")) + { + ListCommand.listCommand(commandSender); + } + else if(args[0].equalsIgnoreCase("start")) + { + StartUhcCommand.startUhcCommand(commandSender, plugin); + } + + // TODO: PERMISSIONS! CONFIG! + + // Check if the args are "textcomponent" and run that command. + /*else if (args[0].equalsIgnoreCase("textcomponent")) + { + // We do not want the console to receive the TextComponent, so we're gonna disable it. + if(senderIsConsole) + { + MessageUtils.sendLocalizedMessage(commandSender.getName(), LocalizedMessages.ERROR_CONSOLE_ACCESS_BLOCKED); + return true; + } + // Everyone else will be able to run the TextComponent message. + TextComponentCommand.textComponentCommand(commandSender); + }*/ + } + return true; + } +} diff --git a/src/net/mindoverflow/network/uhccore/commands/uhccommands/HelpCommand.java b/src/net/mindoverflow/network/uhccore/commands/uhccommands/HelpCommand.java new file mode 100644 index 0000000..354ba40 --- /dev/null +++ b/src/net/mindoverflow/network/uhccore/commands/uhccommands/HelpCommand.java @@ -0,0 +1,13 @@ +package net.mindoverflow.network.uhccore.commands.uhccommands; + +import org.bukkit.command.CommandSender; +import org.bukkit.plugin.Plugin; + +public class HelpCommand +{ + public static void infoCommand(CommandSender commandSender, Plugin plugin) + { + + + } +} diff --git a/src/net/mindoverflow/network/uhccore/commands/uhccommands/ListCommand.java b/src/net/mindoverflow/network/uhccore/commands/uhccommands/ListCommand.java new file mode 100644 index 0000000..9d8a6f5 --- /dev/null +++ b/src/net/mindoverflow/network/uhccore/commands/uhccommands/ListCommand.java @@ -0,0 +1,61 @@ +package net.mindoverflow.network.uhccore.commands.uhccommands; + +import net.mindoverflow.network.uhccore.utils.CommonValues; +import org.bukkit.command.CommandSender; + +import java.util.ArrayList; +import java.util.HashMap; + +public class ListCommand +{ + public static void listCommand(CommandSender commandSender) + { + + HashMap>playersPerTeam = new HashMap<>(); + for(int i = 0; i < CommonValues.totalTeams; i++) + { + ArrayListplayersInThisTeam = new ArrayList<>(); + for(String playerName : CommonValues.playerTeam.keySet()) + { + if(CommonValues.playerTeam.get(playerName).equals(i)) + { + playersInThisTeam.add(playerName); + } + } + playersPerTeam.put(i, playersInThisTeam); + } + + commandSender.sendMessage("§6-------[ UHC: Lista Team ]-------"); + for(Integer i : playersPerTeam.keySet()) + { + String teamName = CommonValues.teamNames.get(i); + int playersInThisTeam = playersPerTeam.get(i).size(); + ArrayListplayersNames = playersPerTeam.get(i); + String playersList = playersNames.toString().replace("[", "").replace("]", "").replace(",", "§7,§r"); + commandSender.sendMessage("" + teamName + " §7(§f" + playersInThisTeam + "§7): §f" + playersList); + } + + /*// Check if player has permissions to see this message. + if(PermissionUtils.playerHasPermission(commandSender.getName(), Permissions.TEXTCOMPONENT_COMMAND)) + { + // Create the TextComponent and give it an initial text. + TextComponent mainComponent = new TextComponent("Hello! "); + // Set the text color for the mainComponent. + mainComponent.setColor(ChatColor.GRAY); + // Create another TextComponent with its own text. + TextComponent subComponent = new TextComponent ("This is clickable!"); + // Set the color for the subComponent. + subComponent.setColor(ChatColor.AQUA); + /// Give the subComponent an HoverEvent that displays a text when the mouse is hovering the TextComponent. + subComponent.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ComponentBuilder("Click here").create())); + // Give the subComponent a ClickEvent that takes action when the TextComponent is clicked. + subComponent.setClickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL, "https://google.com/")); + // Add the subComponent as a second part to the mainComponent. They will simply appear one after the other in a single line. + mainComponent.addExtra(subComponent); + // Add another final text after the subComponent, inheriting the mainComponent's characteristics (ChatColor, HoverEvent, ClickEvent...) + mainComponent.addExtra(" <- click"); + // Pass the Bungeecord message as a Spigot message and send it to the user (probably via packets?) + commandSender.spigot().sendMessage(mainComponent); + }*/ + } +} diff --git a/src/net/mindoverflow/network/uhccore/commands/uhccommands/ReloadCommand.java b/src/net/mindoverflow/network/uhccore/commands/uhccommands/ReloadCommand.java new file mode 100644 index 0000000..80d0ddd --- /dev/null +++ b/src/net/mindoverflow/network/uhccore/commands/uhccommands/ReloadCommand.java @@ -0,0 +1,22 @@ +package net.mindoverflow.network.uhccore.commands.uhccommands; + +import net.mindoverflow.network.uhccore.utils.Debugger; +import net.mindoverflow.network.uhccore.utils.FileUtils; +import org.bukkit.command.CommandSender; + +import java.util.logging.Level; + +public class ReloadCommand +{ + private static Debugger debugger = new Debugger(ReloadCommand.class.getName()); + + public static void reloadCommand(CommandSender commandSender) + { + debugger.sendDebugMessage(Level.INFO, "Reloading YAMLS..."); + commandSender.sendMessage("Reloading YAMLs..."); + FileUtils.checkFiles(); + FileUtils.reloadYamls(); + commandSender.sendMessage("Reloaded YAMLs!"); + debugger.sendDebugMessage(Level.INFO, "Reloaded YAMLs!"); + } +} diff --git a/src/net/mindoverflow/network/uhccore/commands/uhccommands/SetFireworkCommand.java b/src/net/mindoverflow/network/uhccore/commands/uhccommands/SetFireworkCommand.java new file mode 100644 index 0000000..2537b32 --- /dev/null +++ b/src/net/mindoverflow/network/uhccore/commands/uhccommands/SetFireworkCommand.java @@ -0,0 +1,49 @@ +package net.mindoverflow.network.uhccore.commands.uhccommands; + +import net.mindoverflow.network.uhccore.utils.CommonValues; +import net.mindoverflow.network.uhccore.utils.ConfigEntries; +import net.mindoverflow.network.uhccore.utils.Debugger; +import net.mindoverflow.network.uhccore.utils.FileUtils; +import org.bukkit.Location; +import org.bukkit.command.CommandSender; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.entity.Player; + +import java.util.logging.Level; + +public class SetFireworkCommand +{ + + private static Debugger debugger = new Debugger(SetFireworkCommand.class.getName()); + + public static void setFireworkCommand(CommandSender sender) + { + Player player = (Player) sender; + Location fireworkLoc = player.getLocation(); + + YamlConfiguration config = FileUtils.FileType.CONFIG_YAML.yaml; + + int listPos = CommonValues.fireworksLocations.size() + 1; + + if(CommonValues.fireworksLocations.get(0).getWorld() == null) + { + debugger.sendDebugMessage(Level.SEVERE, "WORLD IS NULL!"); + listPos = 1; + CommonValues.fireworksLocations.set(0, fireworkLoc); + } + else + { + CommonValues.fireworksLocations.add(fireworkLoc); + } + + String currentPath = ConfigEntries.FIREWORK_POS.path + "." + listPos; + + config.set(currentPath + ".x", fireworkLoc.getX()); + config.set(currentPath + ".y", fireworkLoc.getY()); + config.set(currentPath + ".z", fireworkLoc.getZ()); + config.set(currentPath + ".world", fireworkLoc.getWorld().getName()); + + FileUtils.FileType.CONFIG_YAML.yaml = config; + FileUtils.saveExistingYaml(FileUtils.FileType.CONFIG_YAML); + } +} diff --git a/src/net/mindoverflow/network/uhccore/commands/uhccommands/SetSpawnCommand.java b/src/net/mindoverflow/network/uhccore/commands/uhccommands/SetSpawnCommand.java new file mode 100644 index 0000000..4fe9203 --- /dev/null +++ b/src/net/mindoverflow/network/uhccore/commands/uhccommands/SetSpawnCommand.java @@ -0,0 +1,32 @@ +package net.mindoverflow.network.uhccore.commands.uhccommands; + +import net.mindoverflow.network.uhccore.utils.CommonValues; +import net.mindoverflow.network.uhccore.utils.ConfigEntries; +import net.mindoverflow.network.uhccore.utils.FileUtils; +import org.bukkit.Location; +import org.bukkit.command.CommandSender; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.entity.Player; + +public class SetSpawnCommand +{ + + public static void setSpawn(CommandSender sender) + { + Player player = (Player) sender; + Location playerLoc = player.getLocation(); + + CommonValues.spawn = playerLoc; + YamlConfiguration config = FileUtils.FileType.CONFIG_YAML.yaml; + config.set(ConfigEntries.SPAWN_WORLD.path, playerLoc.getWorld().getName()); + config.set(ConfigEntries.SPAWN_X.path, playerLoc.getX()); + config.set(ConfigEntries.SPAWN_Y.path, playerLoc.getY()); + config.set(ConfigEntries.SPAWN_Z.path, playerLoc.getZ()); + config.set(ConfigEntries.SPAWN_YAW.path, playerLoc.getYaw()); + config.set(ConfigEntries.SPAWN_PITCH.path, playerLoc.getPitch()); + + FileUtils.FileType.CONFIG_YAML.yaml = config; + + FileUtils.saveExistingYaml(FileUtils.FileType.CONFIG_YAML); + } +} diff --git a/src/net/mindoverflow/network/uhccore/commands/uhccommands/StartUhcCommand.java b/src/net/mindoverflow/network/uhccore/commands/uhccommands/StartUhcCommand.java new file mode 100644 index 0000000..6ff4b6b --- /dev/null +++ b/src/net/mindoverflow/network/uhccore/commands/uhccommands/StartUhcCommand.java @@ -0,0 +1,133 @@ +package net.mindoverflow.network.uhccore.commands.uhccommands; + +import net.mindoverflow.network.uhccore.UhcCore; +import net.mindoverflow.network.uhccore.utils.CommonValues; +import net.mindoverflow.network.uhccore.utils.ConfigEntries; +import net.mindoverflow.network.uhccore.utils.Debugger; +import net.mindoverflow.network.uhccore.utils.FileUtils; +import org.bukkit.*; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import java.util.HashMap; +import java.util.Random; +import java.util.logging.Level; + + +public class StartUhcCommand { + + private static Debugger debugger = new Debugger(StartUhcCommand.class.getName()); + + private static int loadDelay = 10; + + public static void startUhcCommand(CommandSender sender, UhcCore plugin) + { + + HashMap spawnPerTeam = new HashMap<>(); + + World spawnWorld = plugin.getServer().getWorld(CommonValues.uhcWorlds.get(0)); + + int borderX = CommonValues.borderX; + int borderZ = CommonValues.borderZ; + int borderSize = CommonValues.borderSize; + int range = borderSize / 2; + + Location borderCenter = new Location(spawnWorld, borderX, 64, borderZ); + + + for(String playerName : CommonValues.playerTeam.keySet()) + { + Player player = plugin.getServer().getPlayer(playerName); + player.sendTitle("La §dUHC§r inizierà a breve!", "ricerca degli spawnpoint...", 20, 70, 10); + } + + + plugin.getServer().getScheduler().runTaskAsynchronously(plugin, ()-> + { + for(int i = 0; i < CommonValues.totalTeams; i++) + { + + double x = getRandomNumberInRange(borderX - range + 1, borderX + range - 1) + 0.5; + double z = getRandomNumberInRange(borderZ - range + 1, borderZ + range - 1) + 0.5; + int y = spawnWorld.getHighestBlockYAt((int) x, (int) z); + + Location loc = new Location(spawnWorld, x, y + 1, z); + + Location standingBlockLoc = new Location(spawnWorld, x, y, z); + Location upperBlockLoc = new Location(spawnWorld, x, y + 2, z); + Material standingBlockType = standingBlockLoc.getBlock().getType(); + Material upperBlockType = upperBlockLoc.getBlock().getType(); + + spawnPerTeam.put(i, loc); + debugger.sendDebugMessage(Level.INFO, "found block! " + loc); + if(standingBlockType.equals(Material.WATER) || standingBlockType.equals(Material.LAVA) || standingBlockType.equals(Material.AIR) + || !upperBlockType.equals(Material.AIR) || !loc.getBlock().getType().equals(Material.AIR)) + { + debugger.sendDebugMessage(Level.WARNING, "block is not valid: " + standingBlockType + ", " + loc.getBlock().getType() + ", " + upperBlockType); + i--; + } + } + plugin.getServer().getScheduler().runTaskLaterAsynchronously(plugin, ()-> + { + CommonValues.allowMovement = false; + }, 20L); + + plugin.getServer().getScheduler().runTaskLaterAsynchronously(plugin, ()-> + { + CommonValues.allowMovement = true; + }, loadDelay * 20L); + + + for(String playerName : CommonValues.playerTeam.keySet()) + { + int teamNumber = CommonValues.playerTeam.get(playerName); + + Player player = plugin.getServer().getPlayer(playerName); + Location hisTeamLoc = spawnPerTeam.get(teamNumber); + + + + plugin.getServer().getScheduler().runTask(plugin, () -> + { + player.teleport(hisTeamLoc); + player.getInventory().clear(); + player.playSound(player.getLocation(), Sound.BLOCK_NOTE_BLOCK_PLING, 1, 1); + player.sendTitle("Caricamento...", "§7attendi un attimo", 20, 70, 10); + + + + plugin.getServer().getScheduler().runTaskLater(plugin, ()-> + { + player.playSound(player.getLocation(), Sound.ENTITY_PLAYER_LEVELUP, 1, 1); + player.sendTitle("La §dUHC§r è iniziata!", "buona fortuna!", 20, 70, 10); + player.setHealth(20); + player.setFoodLevel(22); + player.setGameMode(GameMode.SURVIVAL); + }, loadDelay * 20L); + }); + } + + plugin.getServer().getScheduler().runTask(plugin, ()-> + { + spawnWorld.setTime(0L); + spawnWorld.setGameRule(GameRule.NATURAL_REGENERATION, false); + spawnWorld.setDifficulty(Difficulty.NORMAL); + spawnWorld.getWorldBorder().setCenter(borderCenter); + spawnWorld.getWorldBorder().setSize(borderSize); + plugin.getLogger().log(Level.INFO,"UHC Started!"); + }); + }); + } + + + private static int getRandomNumberInRange(int min, int max) { + + if (min >= max) { + throw new IllegalArgumentException("max must be greater than min"); + } + + Random r = new Random(); + return r.nextInt((max - min) + 1) + min; + } + +} diff --git a/src/net/mindoverflow/network/uhccore/completers/InfoCompleter.java b/src/net/mindoverflow/network/uhccore/completers/InfoCompleter.java new file mode 100644 index 0000000..d5b9a6a --- /dev/null +++ b/src/net/mindoverflow/network/uhccore/completers/InfoCompleter.java @@ -0,0 +1,49 @@ +package net.mindoverflow.network.uhccore.completers; + +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.command.TabCompleter; + +import java.util.ArrayList; +import java.util.List; + +public class InfoCompleter implements TabCompleter { + @Override + public List onTabComplete(CommandSender commandSender, Command command, String s, String[] args) + { + List list = new ArrayList(); + if(args.length == 1) + { + list.add("help"); + list.add("setspawn"); + list.add("setfirework"); + list.add("start"); + list.add("reload"); + list.add("list"); + if(args[0].startsWith("h")) + { + list.clear(); + list.add("help"); + } else + if(args[0].startsWith("s")) + { + list.clear(); + list.add("setspawn"); + list.add("setfirework"); + list.add("start"); + + } else + if(args[0].startsWith("r")) + { + list.clear(); + list.add("reload"); + } else + if(args[0].equalsIgnoreCase("list")) + { + list.clear(); + list.add("list"); + } + } + return list; + } +} diff --git a/src/net/mindoverflow/network/uhccore/listeners/PlayerChatListener.java b/src/net/mindoverflow/network/uhccore/listeners/PlayerChatListener.java new file mode 100644 index 0000000..c444c57 --- /dev/null +++ b/src/net/mindoverflow/network/uhccore/listeners/PlayerChatListener.java @@ -0,0 +1,51 @@ +package net.mindoverflow.network.uhccore.listeners; + +import net.mindoverflow.network.uhccore.UhcCore; +import net.mindoverflow.network.uhccore.utils.CommonValues; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.player.AsyncPlayerChatEvent; + +public class PlayerChatListener implements Listener { + + private UhcCore plugin; + + public PlayerChatListener(UhcCore givenPlugin) + { + plugin = givenPlugin; + } + + + // Event called whenever a player sends a chat message. + @EventHandler(priority = EventPriority.HIGH) + public void onPlayerChat(AsyncPlayerChatEvent event) + { + + // Store the player's name, his display name, and the sent message. + String playerName = event.getPlayer().getName(); + String displayName = event.getPlayer().getDisplayName(); + String message; + + // Check if the player is in a team. + if(CommonValues.playerTeam.containsKey(playerName)) + { + // Load the team number and the team name from that. + int teamNumber = CommonValues.playerTeam.get(playerName); + String teamName = CommonValues.teamNames.get(teamNumber); + + // Build the chat message. + message = "§7[" + teamName + "§7] §f" + displayName + "§7: " + event.getMessage(); + } else // Else, if the player is not in any team... + { + // Just fomat the message. + message = "§f" + displayName + "§7: " + event.getMessage(); + } + + // cancel the event (we want to send our own custom message) + event.setCancelled(true); + + // and finally broadcast the message. + plugin.getServer().broadcastMessage(message); + } +} diff --git a/src/net/mindoverflow/network/uhccore/listeners/PlayerDeathRespawnListener.java b/src/net/mindoverflow/network/uhccore/listeners/PlayerDeathRespawnListener.java new file mode 100644 index 0000000..7ecf63c --- /dev/null +++ b/src/net/mindoverflow/network/uhccore/listeners/PlayerDeathRespawnListener.java @@ -0,0 +1,253 @@ +package net.mindoverflow.network.uhccore.listeners; + +import net.mindoverflow.network.uhccore.UhcCore; +import net.mindoverflow.network.uhccore.utils.CommonValues; +import net.mindoverflow.network.uhccore.utils.Debugger; +import org.bukkit.*; +import org.bukkit.entity.Firework; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.event.entity.PlayerDeathEvent; +import org.bukkit.event.player.PlayerRespawnEvent; + +import java.util.HashMap; +import java.util.logging.Level; + +public class PlayerDeathRespawnListener implements Listener +{ + + private UhcCore plugin; + + public PlayerDeathRespawnListener(UhcCore givenPlugin) + { + plugin = givenPlugin; + } + + + Debugger debugger = new Debugger(getClass().getName()); + // HashMap containing players who died during the UHC, and their death location. + // we need this so we can teleport them there as spectators once they respawn. + private HashMapdeadPlayers = new HashMap<>(); + + private boolean isTaskScheduled = false; + int taskID, times; + + + // Event called when the player dies. + @EventHandler + public void onPlayerDeath(PlayerDeathEvent event) + { + + Player player = event.getEntity(); + + // Remove the Teams selector item from the drops. + event.getDrops().remove(CommonValues.teamsItem); + + // Check if the player died in the lobby... + if(CommonValues.lobbyWorlds.contains(player.getWorld().getName())) + { + // And clear all drops. + event.getDrops().clear(); + } + + + + // check if the death world is a UHC world (we don't want this to happen in the lobby!) + // and + // check if the player is in any team (players who are not in a team are not playing!) + if((CommonValues.uhcWorlds.contains(player.getWorld().getName())) && CommonValues.playerTeam.containsKey(player.getName())) + { + + // Spawn a Firework where the player died. + CommonValues.spawnFirework(plugin, player.getLocation(), 15L); + + // Load the player name. + String playerName = player.getName(); + + // Store the player name and his death location. + deadPlayers.put(playerName, player.getLocation()); + + // Load the dead player's team number. + int thisPlayerTeamNumber = CommonValues.playerTeam.get(playerName); + // Load the death player's team name. + String thisPlayerTeamName = CommonValues.teamNames.get(thisPlayerTeamNumber); + // Remove the player from his team. + CommonValues.playerTeam.remove(playerName); + + + // Run this task Async, because it may be CPU heavy. + plugin.getServer().getScheduler().runTaskAsynchronously(plugin, () -> + + { + // Update the total number of players in each team, and the total number of alive teams. + CommonValues.updatePlayersPerTeam(); + + // Check how many players are left in the dead player's team. + int thisPlayerTeamPlayers = CommonValues.playersPerTeam.get(thisPlayerTeamNumber); + + // Run this task Sync, because we need to access the API, and also delay it by 1 second. + plugin.getServer().getScheduler().runTaskLater(plugin, () -> + { + + int playingPlayers = CommonValues.playerTeam.size(); + for(Player p : plugin.getServer().getOnlinePlayers()) + { + p.playSound(p.getLocation(), Sound.BLOCK_NOTE_BLOCK_PLING, 1, 1); + } + plugin.getServer().broadcastMessage(playerName + "§7 del team §e" + thisPlayerTeamName + "§7 è fuori gioco!"); + plugin.getServer().broadcastMessage("§7Nel team " + thisPlayerTeamName + "§7 rimangono §e" + thisPlayerTeamPlayers + "§7 giocatori."); + plugin.getServer().broadcastMessage("§7In totale rimangono §e" + playingPlayers + "§7 giocatori, in §e" + CommonValues.playingTeams + "§7 team."); + + if(CommonValues.playingTeams <= 1) + { + CommonValues.allowMovement = false; + scheduleTask(); + plugin.getServer().broadcastMessage("§6La UHC è finita!"); + + int winningTeam = 0; + for(int i = 0; i < CommonValues.totalTeams; i++) + { + if(CommonValues.playersPerTeam.get(i) > 0) + { + winningTeam = i; + } + } + + String teamName = CommonValues.teamNames.get(winningTeam) + "§r"; + plugin.getServer().broadcastMessage("§6Ha vinto il team: " + teamName); + + + + for(Player currentPlayer : plugin.getServer().getOnlinePlayers()) + { + currentPlayer.teleport(CommonValues.spawn); + // Clear his inventory and give him the Teams selector item. + CommonValues.giveTeamsSelectorItem(currentPlayer); + plugin.getLogger().log(Level.INFO,"UHC Finished!"); + currentPlayer.sendTitle("Team " + teamName + " Vincitore!", "", 20 * 2, 20 * 10, 20 * 2); + + for(Player hiddenPlayer : plugin.getServer().getOnlinePlayers()) + { + currentPlayer.hidePlayer(plugin, hiddenPlayer); + } + } + } + }, 20L); + }); + + } + } + + // Event called when a player respawns. + @EventHandler + public void onPlayerRespawn(PlayerRespawnEvent event) + { + // Load the player value. + Player player = event.getPlayer(); + + // Check if the player died during the UHC, so we can get his death location. + if(deadPlayers.containsKey(event.getPlayer().getName())) + { + + // Run this task delayed, so we don't have any interference from other plugins. + plugin.getServer().getScheduler().runTaskLater(plugin, () -> + { + + + // Check if there is more than 1 team alive. + // If there is only 1 team alive, then the UHC is over. + if(CommonValues.playingTeams > 1) + { + // warn the player that he's not a spectator. + player.sendMessage("§cSei morto nella UHC e ora sei uno spettatore!"); + + // teleport him to his death location. + player.teleport(deadPlayers.get(player.getName())); + + // wait 0,5s and set his gamemode to spectator. + plugin.getServer().getScheduler().runTaskLater(plugin, () -> { + player.setGameMode(GameMode.SPECTATOR); + }, 10L); + } + else + { + plugin.getServer().getScheduler().runTaskLater(plugin, () -> + { + CommonValues.tpSpawnAndGiveItem(player); + }, 10L); + } + + deadPlayers.remove(player.getName()); + + }, 20L); + } + else + { + + plugin.getServer().getScheduler().runTaskLater(plugin, () -> + { + CommonValues.tpSpawnAndGiveItem(player); + }, 10L); + } + + + } + + @EventHandler + public void onEntityDamage(EntityDamageByEntityEvent event) + { + if(event.getDamager() instanceof Firework) + { + event.setDamage(0.0); + event.setCancelled(true); + } + } + + private void scheduleTask() + { + if(isTaskScheduled)return; + isTaskScheduled = true; + + taskID = plugin.getServer().getScheduler().runTaskTimer(plugin, () -> + { + times++; + if(times == 10) + { + times = 0; + plugin.getServer().getScheduler().cancelTask(taskID); + taskID = 0; + } + + for(Location loc : CommonValues.fireworksLocations) + { + debugger.sendDebugMessage(Level.INFO, "FIREWORK LOC: " + loc); + CommonValues.spawnFirework(plugin, loc, 10L); + } + + + }, 20L, 20L).getTaskId(); + + + + + plugin.getServer().getScheduler().runTaskLater(plugin, ()-> + { + isTaskScheduled = false; + CommonValues.allowMovement = true; + + for (Player currentPlayer : plugin.getServer().getOnlinePlayers()) + { + for(Player hiddenPlayer : plugin.getServer().getOnlinePlayers()) + { + currentPlayer.showPlayer(plugin, hiddenPlayer); + } + } + }, 20L * 10L); + + + } + + +} diff --git a/src/net/mindoverflow/network/uhccore/listeners/PlayerHitListener.java b/src/net/mindoverflow/network/uhccore/listeners/PlayerHitListener.java new file mode 100644 index 0000000..1b81aa8 --- /dev/null +++ b/src/net/mindoverflow/network/uhccore/listeners/PlayerHitListener.java @@ -0,0 +1,43 @@ +package net.mindoverflow.network.uhccore.listeners; + +import net.mindoverflow.network.uhccore.utils.CommonValues; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.EntityDamageByEntityEvent; + +public class PlayerHitListener implements Listener +{ + + // Event called when someone hits someone else. + @EventHandler + public void onPlayerHitPlayer(EntityDamageByEntityEvent event) + { + // if friendly fire is enabled, then skip everything that follows and let the hit happen. + if(CommonValues.friendlyFire) return; + + // check if the damaged and damager entities are both players. If they're not, stop. + if(!(event.getDamager() instanceof Player && event.getEntity() instanceof Player)) + { + return; + } + + // Load the damaged and damager's names. + String damagedName = event.getEntity().getName(); + String damagerName = event.getDamager().getName(); + + // Check if they're in a team. if they're not, stop. + if(!(CommonValues.playerTeam.containsKey(damagedName) && CommonValues.playerTeam.containsKey(damagerName))) + { + return; + } + + // check if they're both in the same team. + if(CommonValues.playerTeam.get(damagedName).equals(CommonValues.playerTeam.get(damagerName))) + { + // cancel the event. + event.setCancelled(true); + event.getDamager().sendMessage("§cNon puoi colpire un tuo amico!"); + } + } +} diff --git a/src/net/mindoverflow/network/uhccore/listeners/PlayerInteractListener.java b/src/net/mindoverflow/network/uhccore/listeners/PlayerInteractListener.java new file mode 100644 index 0000000..dde787d --- /dev/null +++ b/src/net/mindoverflow/network/uhccore/listeners/PlayerInteractListener.java @@ -0,0 +1,119 @@ +package net.mindoverflow.network.uhccore.listeners; + + +import net.mindoverflow.network.uhccore.utils.CommonValues; +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.PlayerDropItemEvent; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +public class PlayerInteractListener implements Listener +{ + + // Event called when someone interacts with the world. + @EventHandler + public void onPlayerInteract(PlayerInteractEvent event) + { + // Check if the action was a right click. + Action action = event.getAction(); + if(action.equals(Action.RIGHT_CLICK_AIR) || action.equals(Action.RIGHT_CLICK_BLOCK)) + { + + Player player = event.getPlayer(); + + // check if the player's item in hand was the Teams selector item. + if(player.getInventory().getItemInMainHand().equals(CommonValues.teamsItem)) + { + // Open the teams selector GUI. + player.openInventory(CommonValues.teamsSelectorGUI.getInventory()); + } + } + } + + // Event called when someone clicks inside of an inventory. + @EventHandler + public void onPlayerInventoryClick(InventoryClickEvent event) + { + + // Check if any of the inventories is null, and return. + if(event.getClickedInventory() == null) return; + if(event.getCurrentItem() == null) return; + + // Get the clicked item. + ItemStack item = event.getCurrentItem(); + + // Check if the clicked inventory is the Teams selector GUI. + if(event.getClickedInventory().equals(CommonValues.teamsSelectorGUI.getInventory())) + { + // Cancel the event (we don't want items to be moved!) + event.setCancelled(true); + + // Load the item's item meta. + ItemMeta im = item.getItemMeta(); + // if it's null, return. + if(im == null) return; + + // Load the player and close his inventory. + Player player = (Player) event.getWhoClicked(); + player.closeInventory(); + + // Check if the clicked item is an existing Team. + if(CommonValues.teamNames.contains(im.getDisplayName())) + { + + // Load the team number from the team name in the teams list. + int teamNumber = CommonValues.teamNames.indexOf(im.getDisplayName()); + + // Add the player to that team. + CommonValues.playerTeam.remove(player.getName()); + CommonValues.playerTeam.put(player.getName(), teamNumber); + + // Update the total number of players in each team, and the total number of alive teams. + CommonValues.updatePlayersPerTeam(); + + // Tell the player he has joined a team. + player.sendMessage("§7Aggiunto al team " + im.getDisplayName()); + } + // Else, check if the clicked item is the one used to quit teams. + else if(item.equals(CommonValues.quitTeamItem)) + { + // Check if the player is in any team. + if(CommonValues.playerTeam.containsKey(player.getName())) + { + // Remove the player from the team. + player.sendMessage("§eRimosso dal Team!"); + CommonValues.playerTeam.remove(player.getName()); + + // Update the total number of players in each team, and the total number of alive teams. + CommonValues.updatePlayersPerTeam(); + } else + { + player.sendMessage("§cIn nessun team!"); + } + } + } // Check if the non-clicked inventory (there always are two inventories) is the Teams selector GUI, and cancel the event (we don't want items to be put inside of it!) + else if(event.getInventory().equals(CommonValues.teamsSelectorGUI.getInventory())) event.setCancelled(true); + + // Prevent everyone from moving the Teams selector item in their inventory. + if(item.equals(CommonValues.teamsItem)) event.setCancelled(true); + } + + + + // Event called when an item is dropped. + @EventHandler + public void onItemDrop(PlayerDropItemEvent event) + { + // Check if the dropped item is the Teams selector item. + if(event.getItemDrop().getItemStack().equals(CommonValues.teamsItem)) + { + // Prevent it from being dropped. + event.setCancelled(true); + } + } +} diff --git a/src/net/mindoverflow/network/uhccore/listeners/PlayerJoinListener.java b/src/net/mindoverflow/network/uhccore/listeners/PlayerJoinListener.java new file mode 100644 index 0000000..e1fc789 --- /dev/null +++ b/src/net/mindoverflow/network/uhccore/listeners/PlayerJoinListener.java @@ -0,0 +1,37 @@ +package net.mindoverflow.network.uhccore.listeners; + +import net.mindoverflow.network.uhccore.utils.CommonValues; +import net.mindoverflow.network.uhccore.utils.Debugger; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +import java.util.logging.Level; + +public class PlayerJoinListener implements Listener +{ + // Instantiate a Debugger for this class. + private Debugger debugger = new Debugger(getClass().getName()); + + + + // Call EventHandler and start listening to joining players. + @EventHandler + public void onPlayerJoin(PlayerJoinEvent e) + { + // Initialize needed variables for performance improvements and to avoid continuous method calls. + Player player = e.getPlayer(); + + + if(!(CommonValues.playerTeam.containsKey(player.getName()))) + { + CommonValues.tpSpawnAndGiveItem(player); + } + + + } +} diff --git a/src/net/mindoverflow/network/uhccore/listeners/PlayerMoveListener.java b/src/net/mindoverflow/network/uhccore/listeners/PlayerMoveListener.java new file mode 100644 index 0000000..402be4c --- /dev/null +++ b/src/net/mindoverflow/network/uhccore/listeners/PlayerMoveListener.java @@ -0,0 +1,32 @@ +package net.mindoverflow.network.uhccore.listeners; + +import net.mindoverflow.network.uhccore.UhcCore; +import net.mindoverflow.network.uhccore.utils.CommonValues; +import net.mindoverflow.network.uhccore.utils.Debugger; +import org.bukkit.Location; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerMoveEvent; +import org.bukkit.scheduler.BukkitTask; + +import java.util.logging.Level; + +public class PlayerMoveListener implements Listener +{ + + private UhcCore plugin; + public PlayerMoveListener(UhcCore givenPlugin) + { + plugin = givenPlugin; + } + + //Debugger debugger = new Debugger(getClass().getName()); + + @EventHandler + public void onPlayerMove(PlayerMoveEvent event) + { + if(CommonValues.allowMovement) return; + event.setCancelled(true); + } +} diff --git a/src/net/mindoverflow/network/uhccore/listeners/TeamsSelectorGUI.java b/src/net/mindoverflow/network/uhccore/listeners/TeamsSelectorGUI.java new file mode 100644 index 0000000..2acdc68 --- /dev/null +++ b/src/net/mindoverflow/network/uhccore/listeners/TeamsSelectorGUI.java @@ -0,0 +1,53 @@ +package net.mindoverflow.network.uhccore.listeners; + +import net.mindoverflow.network.uhccore.utils.CommonValues; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.InventoryHolder; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +import java.util.LinkedHashMap; + +public class TeamsSelectorGUI implements InventoryHolder +{ + + private final Inventory inv; + + public TeamsSelectorGUI() + { + inv = Bukkit.createInventory(this, 18, "Team"); + } + + public Inventory getInventory() + { + return inv; + } + + public void initializeInv() + { + + for(int i = 0; i < CommonValues.totalTeams; i++) + { + String teamName = CommonValues.teamNames.get(i); + Material itemMat = CommonValues.teamItemsMaterials.get(i); + inv.setItem(i, createItem(teamName, itemMat)); + } + + + inv.setItem(17, CommonValues.quitTeamItem); + + } + + private ItemStack createItem(String name, Material material) + { + ItemStack item = new ItemStack(material, 1); + ItemMeta im = item.getItemMeta(); + im.setDisplayName(name); + item.setItemMeta(im); + + return item; + } + +} diff --git a/src/net/mindoverflow/network/uhccore/utils/CommonValues.java b/src/net/mindoverflow/network/uhccore/utils/CommonValues.java new file mode 100644 index 0000000..fde6427 --- /dev/null +++ b/src/net/mindoverflow/network/uhccore/utils/CommonValues.java @@ -0,0 +1,123 @@ +package net.mindoverflow.network.uhccore.utils; + +import net.mindoverflow.network.uhccore.UhcCore; +import net.mindoverflow.network.uhccore.listeners.TeamsSelectorGUI; +import org.bukkit.Color; +import org.bukkit.FireworkEffect; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Firework; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.FireworkMeta; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +public class CommonValues { + + // Values to save the uhc and lobby world names. + public static List uhcWorlds = new ArrayList<>(), lobbyWorlds = new ArrayList<>(); + + // HashMap containing the number of players teamPlayers for every team teamNumber. + public static HashMap playersPerTeam = new HashMap<>(); + + // Integer to store how many teams are alive and playing. + public static int playingTeams; + + // Boolean to know if friendly fire is enabled, and to know if movement is allowed. + public static boolean friendlyFire, allowMovement = true; + + // ItemStacks to store the "team selector" and "quit team" items + data. + public static ItemStack teamsItem, quitTeamItem; + + // Int to know how many teams are enabled. + public static int totalTeams; + + // Instance of the Teams Selector GUI, so we can access it from anywhere. + public static TeamsSelectorGUI teamsSelectorGUI; + + // ArrayList with all teams' names, ordered. + public static List teamNames = new ArrayList<>(); + + // ArrayList with all teams' representative items, ordered. + public static List teamItemsMaterials = new ArrayList<>(); + + // HashMap to know in which team number is a certain player + // + // Team number is the teamNames[n] number, starting from 0. + public static HashMap playerTeam = new HashMap<>(); + + // Location to store the UHC spawn/win location. + public static Location spawn; + + public static ListfireworksLocations = new ArrayList<>(); + + + public static int borderX, borderZ, borderSize; + + // Function to check how many players a team has. + // This function returns the total number of alive teams. + public static void updatePlayersPerTeam() + { + // Integer to check how many teams are left alive. + int playingTeams = 0; + + // Iterate through every existing team. + for(int i = 0; i < totalTeams; i++) + { + // Int to store the players number for each team. + int playersNumber = 0; + + // Iterate through every player and... + for(String s : playerTeam.keySet()) + { + //if his team is the current checked one... + if(playerTeam.get(s) == i) + { + //increase the playersNumber by 1. + playersNumber++; + } + } + + // Finally, put the team number and his player count in the playersPerTeam HashMap. + playersPerTeam.put(i, playersNumber); + + // If there is at least 1 player in this team, then count this as an "alive team". + if(playersNumber != 0) playingTeams++; + } + + // Return the number of alive teams. + CommonValues.playingTeams = playingTeams; + } + + public static void giveTeamsSelectorItem(Player player) + { + + player.getInventory().clear(); + player.getInventory().setItem(4, CommonValues.teamsItem); + } + + public static void spawnFirework(UhcCore plugin, Location location, long detonateDelay) { + + Firework firework = (Firework) location.getWorld().spawnEntity(location, EntityType.FIREWORK); + FireworkMeta fireworkMeta = firework.getFireworkMeta(); + + fireworkMeta.setPower(100); + fireworkMeta.addEffect(FireworkEffect.builder().withColor(Color.RED).flicker(true).build()); + + firework.setFireworkMeta(fireworkMeta); + plugin.getServer().getScheduler().runTaskLater(plugin, firework::detonate, detonateDelay); + } + + public static void tpSpawnAndGiveItem(Player player) + { + + player.teleport(spawn); + + // Clear the player's inventory and give hims the Teams selector item. + giveTeamsSelectorItem(player); + } +} diff --git a/src/net/mindoverflow/network/uhccore/utils/ConfigEntries.java b/src/net/mindoverflow/network/uhccore/utils/ConfigEntries.java new file mode 100644 index 0000000..3d57afa --- /dev/null +++ b/src/net/mindoverflow/network/uhccore/utils/ConfigEntries.java @@ -0,0 +1,36 @@ +package net.mindoverflow.network.uhccore.utils; + +public enum ConfigEntries +{ + UHC_WORLDS("settings.uhcworlds"), + + LOBBY_WORLDS("settings.lobbyworlds"), + + FRIENDLY_FIRE("settings.friendly-fire"), + + TEAMS_NUMBER("settings.teams"), + TEAMS_NAMES("teams"), + TEAMS_ITEMS("team-items"), + + SPAWN_WORLD("spawn.world"), + SPAWN_X("spawn.x"), + SPAWN_Y ("spawn.y"), + SPAWN_Z("spawn.z"), + SPAWN_PITCH("spawn.pitch"), + SPAWN_YAW("spawn.yaw"), + + FIREWORK_POS("firework-pos"), + + BORDER_CENTER_X("settings.border.center-x"), + BORDER_CENTER_Z("settings.border.center-z"), + BORDER_SIZE("settings.border.size"), + + ; + + public String path; + + ConfigEntries(String path) + { + this.path = path; + } +} diff --git a/src/net/mindoverflow/network/uhccore/utils/Debugger.java b/src/net/mindoverflow/network/uhccore/utils/Debugger.java new file mode 100644 index 0000000..a835758 --- /dev/null +++ b/src/net/mindoverflow/network/uhccore/utils/Debugger.java @@ -0,0 +1,87 @@ +package net.mindoverflow.network.uhccore.utils; + +import net.mindoverflow.network.uhccore.UhcCore; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; + +import java.util.UUID; +import java.util.logging.Level; + +public class Debugger +{ + // Enable or disable debugging messages (aka verbosity). + private final boolean DEBUGGING = false; + + // Initialize needed variables. We will need those variables to be able to precisely debug the plugin. + private String className; + private String packageName; + + // Save my UUID and current Username somewhere so I can get debug messages too. + private UUID authorUUID = UUID.fromString("297a1dc8-c0a3-485a-ad21-8956c749f927"); + private String authorName = "mind_overflow"; + + // Make a constructor requiring to be given a class so we exactly know which class has made an instance of it and all of its properties. + public Debugger(String instanceClassName) + { + // Only run this code and actually make a whole instance of the class only if debugging is active. + if(DEBUGGING) + { + // Initializing the class variable and set it to this one: in case something bad happens, we still have the log without the class info. + Class instanceClass = getClass(); + try + { + /* + * Try finding the instancing class. This is normally bad for performance as we have to search for the class since we only have its name + * but the only other way would have been to always instantiate a whole class instead of a single String, making the plugin resource + * hungry even if the Debugger was disabled. + */ + instanceClass = Class.forName(instanceClassName); + } + catch (ClassNotFoundException e) + { + // In case it throws an error, go mad and report it in console. + UhcCore.logger.log(Level.INFO, "WTF? A class made an instance of the Debugger but it somehow can't define which class was it. Very weird. Setting it to the Debugger class."); + UhcCore.logger.log(Level.INFO, "Please send the following error log to me (" + authorName + "):"); + e.printStackTrace(); + } + // Give the instance's variables their respective values. + className = instanceClass.getSimpleName(); + packageName = instanceClass.getPackage().getName(); + } + + } + + + /* + * Check if debugging is enabled and eventually send debug logs. No need to worry about some of this data being null as there already are + * checks and fixed for that in the constructor. Also, the debugger must be instanced for this method to be called (it's not static), so + * we already have the info we need thanks to that. + */ + public void sendDebugMessage(Level lvl, String str) + { + + // Check if debugging is enabled. + if(DEBUGGING) + { + + // Put together all the info we have in a single String. + String msg = className + ": " + str; + + // Send the info to the server log. + UhcCore.logger.log(lvl, msg); + + // Check if I'm online and if I am, send me the same info. + Player author = Bukkit.getPlayer(authorUUID); + if(author == null) { + author = Bukkit.getPlayer(authorName); + } + if(author != null) + { + if(Bukkit.getServer().getOnlinePlayers().contains(author)) + { + author.sendMessage(msg); + } + } + } + } +} diff --git a/src/net/mindoverflow/network/uhccore/utils/FileUtils.java b/src/net/mindoverflow/network/uhccore/utils/FileUtils.java new file mode 100644 index 0000000..5e9d0d1 --- /dev/null +++ b/src/net/mindoverflow/network/uhccore/utils/FileUtils.java @@ -0,0 +1,287 @@ +package net.mindoverflow.network.uhccore.utils; + +import net.mindoverflow.network.uhccore.UhcCore; +import net.mindoverflow.network.uhccore.listeners.TeamsSelectorGUI; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.World; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import sun.security.krb5.Config; + +import java.io.*; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.logging.Level; + +public class FileUtils +{ + + // Instantiate a Debugger for this class. + private static Debugger debugger = new Debugger(FileUtils.class.getName()); + + // Necessary variables. + private static UhcCore plugin; + + public FileUtils(UhcCore plugin) { + FileUtils.plugin = plugin; + } + + private static void copyFileFromSrc(FileType givenFileType) + { + // Check if files already exists and if it doesn't, then create it. + if(!givenFileType.file.exists()) + { + // Load the InputStream of the file in the source folder. + InputStream is = FileUtils.class.getResourceAsStream("/" + givenFileType.file.getName()); + try + { + // Try copying the file to the directory where it's supposed to be, and log it. + Files.copy(is, Paths.get(givenFileType.file.getAbsolutePath())); + is.close(); + debugger.sendDebugMessage(Level.INFO, "File " + givenFileType.file.getName() + " successfully created."); + } + catch (IOException e) + { + // Throw exception if something went wrong (lol, I expect this to happen since we're working with files in different systems) + UhcCore.logger.log(Level.SEVERE, "There were some unexpected errors from " + givenFileType.file.getName() + " file creation. Please contact the developer and send him this log:"); + e.printStackTrace(); + } + + } + } + + // As method says, reload YamlConfigurations by overwriting their previous value. + public static void reloadYamls() + { + FileType.CONFIG_YAML.yaml = YamlConfiguration.loadConfiguration(FileType.CONFIG_YAML.file); + FileType.LANG_YAML.yaml = YamlConfiguration.loadConfiguration(FileType.LANG_YAML.file); + + CommonValues.playerTeam.clear(); + CommonValues.playersPerTeam.clear(); + CommonValues.teamNames.clear(); + CommonValues.teamItemsMaterials.clear(); + CommonValues.spawn = null; + CommonValues.fireworksLocations.clear(); + + CommonValues.playingTeams = 0; + + YamlConfiguration config = FileType.CONFIG_YAML.yaml; + + CommonValues.teamNames = config.getStringList(ConfigEntries.TEAMS_NAMES.path); + for(String matName : config.getStringList(ConfigEntries.TEAMS_ITEMS.path)) + { + CommonValues.teamItemsMaterials.add(Material.valueOf(matName)); + } + + CommonValues.uhcWorlds = config.getStringList(ConfigEntries.UHC_WORLDS.path); + CommonValues.lobbyWorlds = config.getStringList(ConfigEntries.LOBBY_WORLDS.path); + + CommonValues.friendlyFire = config.getBoolean(ConfigEntries.FRIENDLY_FIRE.path); + + CommonValues.teamsItem = new ItemStack(Material.NETHER_STAR); + ItemMeta im = CommonValues.teamsItem.getItemMeta(); + im.setDisplayName("§eTeam"); + CommonValues.teamsItem.setItemMeta(im); + + CommonValues.quitTeamItem = new ItemStack(Material.BARRIER); + im = CommonValues.quitTeamItem.getItemMeta(); + im.setDisplayName("§cEsci dal Team"); + CommonValues.quitTeamItem.setItemMeta(im); + + CommonValues.totalTeams = config.getInt(ConfigEntries.TEAMS_NUMBER.path); + + CommonValues.teamsSelectorGUI = new TeamsSelectorGUI(); + CommonValues.teamsSelectorGUI.initializeInv(); + + CommonValues.borderX = config.getInt(ConfigEntries.BORDER_CENTER_X.path); + CommonValues.borderZ = config.getInt(ConfigEntries.BORDER_CENTER_Z.path); + CommonValues.borderSize = config.getInt(ConfigEntries.BORDER_SIZE.path); + + String spawnWorldName = config.getString(ConfigEntries.SPAWN_WORLD.path); + if(spawnWorldName != null) + { + World spawnWorld = plugin.getServer().getWorld(spawnWorldName); + + if(spawnWorld != null) + { + double x = config.getDouble(ConfigEntries.SPAWN_X.path); + double y = config.getDouble(ConfigEntries.SPAWN_Y.path); + double z = config.getDouble(ConfigEntries.SPAWN_Z.path); + double yaw = config.getDouble(ConfigEntries.SPAWN_YAW.path); + double pitch = config.getDouble(ConfigEntries.SPAWN_PITCH.path); + CommonValues.spawn = new Location(spawnWorld, x, y, z, (float) yaw, (float) pitch); + } + } + + for(String s : config.getConfigurationSection(ConfigEntries.FIREWORK_POS.path).getKeys(false)) + { + String currentPath = ConfigEntries.FIREWORK_POS.path + "." + s; + String world = config.getString(currentPath + ".world"); + double x = config.getDouble(currentPath + ".x"); + double y = config.getDouble(currentPath + ".y"); + double z = config.getDouble(currentPath + ".z"); + + CommonValues.fireworksLocations.add(new Location(plugin.getServer().getWorld(world), x, y, z)); + } + + } + + // Only reload the needed File. + public static void reloadYaml(FileType yamlFile) + { + yamlFile.yaml = YamlConfiguration.loadConfiguration(yamlFile.file); + debugger.sendDebugMessage(Level.INFO, "File " + yamlFile.file.getName() + " YAML loaded."); + } + + // Save a Yaml file from the list of the plugin's YamlFiles enum. + public static void saveExistingYaml(FileType yamlFile) + { + // Get the actual File and its location. + File configFile = yamlFile.file; + try { + // Try saving the value in FileType.NAME.yaml into the file itself we just got. Else, it would only be saved in RAM and then be lost after unloading the plugin. + yamlFile.yaml.save(configFile); + debugger.sendDebugMessage(Level.INFO, "Successfully saved " + configFile.getName() +" (YAML)!"); + } catch (IOException e) { + debugger.sendDebugMessage(Level.SEVERE, "Error in saving " + configFile.getName() + "(YAML)!"); + e.printStackTrace(); + } + + // Reload the Yaml configuration from the file, just in case. + reloadYaml(yamlFile); + } + + + // Check if all needed files exist and work correctly. + public static void checkFiles() { + // Check if the different needed files and folders exist and if not, try creating them. + // Check if plugin folder exists and eventually make it. Easy enough. + if(!plugin.getDataFolder().exists()) + { + if(plugin.getDataFolder().mkdir()) + { + debugger.sendDebugMessage(Level.INFO, "Plugin dir successfully created."); + } + } + + // Check and eventually create config file. + copyFileFromSrc(FileType.CONFIG_YAML); + // Reload file YAML data into FileType.NAME.yaml. + reloadYaml(FileType.CONFIG_YAML); + // Check if there is any missing entry. + checkYamlMissingEntries(FileType.CONFIG_YAML); + + // Check and eventually create players file. + copyFileFromSrc(FileType.LANG_YAML); + // Reload file YAML data into FileType.NAME.yaml. + reloadYaml(FileType.LANG_YAML); + // Check if there is any missing entry. + checkYamlMissingEntries(FileType.LANG_YAML); + + + UhcCore.logger.log(Level.INFO, "All files are working correctly."); + } + + + private static void checkYamlMissingEntries(FileType givenFile) + { + /* + Load the file from source so we can check if the file in the plugin directory is missing any entries. + Since our file is not an actual file on the filesystem but rather a compressed file in the jar archive, + we can't directly access it via a "File file = new File();" method. To do it, we'd need to extract + the file from the archive to a temporary file, read it and then delete it. + + The choice of making an InputStream instead is better because we don't risk leaving junk files + in the filesystem and we can achieve the same objective without so many resource-consuming passages. + */ + + // First of all, we're gonna get the InputStream of the file from the jar archive. + InputStream is = FileUtils.class.getResourceAsStream("/" + givenFile.file.getName()); + + // Then, we're gonna make a Reader because we don't want to save it as a file but only load it in memory. + // Bukkit's YamlConfiguration accepts Readers so this is perfect! + Reader targetReader = new InputStreamReader(is); + + // Load its YamlConfiguration. + YamlConfiguration srcYaml = YamlConfiguration.loadConfiguration(targetReader); + + // Iterate each entry in the YamlConfiguration. + debugger.sendDebugMessage(Level.INFO, "Iterating src config entries for file " + givenFile.file.getName() + "."); + + /* For each String which we'll name 'key' in the Set of entries of the yaml file, do... + + getKeys(true) returns all the entries and all the sub-entries, which is what we need because + we want to check the whole file for missing entries. + If we wanted to only load an entry with the highest level sub-entries, we would just pass 'false' + as an argument. + + Example + ---- FILE ---------------- + hello: 'this is a string' + myname: 4 + islorenzo: 8 + who: true + areu: '?' + john: false + -------------------------- + + Set keys = srcYaml.getConfigurationSection("path").getKeys(true); + + By saving our set with 'false' as an argument, and "" as the path (which means the highest level of the file), + we'd only get the 'hello' String and the 'john' boolean's value in the set. + + By saving our set with 'false' as an argument, and "hello" as the path (which means the highest level of the + 'hello' entry), we'd only get the 'hello' String's value and the 'hello.myname' and 'hello.islorenzo' booleans' values in the set. + + By saving our set with 'true' as an argument, and "" as the path (which means the highest level of the file + with all its sub-entries), we'd get the value of all entries in the whole file ('hello', 'hello.myname', 'hello.islorenzo', + 'hello.islorenzo.who', 'hello.islorenzo.areu', 'john') in the set. + + By saving our set with 'true' as an argument, and "hello" as the path (which means the highest level of the + 'hello' entry with all its sub-entries), we'd get the value of all entries in the 'hello' entry ('hello', 'hello.myname', + 'hello.islorenzo', 'hello.islorenzo.who', 'hello.islorenzo.areu') in the set. + */ + for (String key : srcYaml.getConfigurationSection("").getKeys(true)) + { + debugger.sendDebugMessage(Level.INFO, "Analyzing key '" + key + "' with default value '" + srcYaml.get(key) + "'."); + + // Check if file is missing every entry. + if(!givenFile.yaml.contains(key)) + { + debugger.sendDebugMessage(Level.WARNING, "Config file is missing '" + key + "' key! Proceeding to add it..."); + // Add the entry to the file. + givenFile.yaml.set(key, srcYaml.get(key)); + debugger.sendDebugMessage(Level.WARNING, "Added key '" + key + "' with value '" + srcYaml.get(key) + "'."); + // Save the file! + saveExistingYaml(givenFile); + } + } + debugger.sendDebugMessage(Level.INFO, "Done iterating src config entries for file " + givenFile.file.getName() + "!"); + } + // Save all the info about our files location. + /* + Also initialize all files and their config, so we know where are the files when we need to save or reload them. + this is better than loading the files in the single classes that use them as if we had to reload them, we'd + need to set them again in each of the classes. Doing this instead allows us to have them all in one place. + */ + public enum FileType + { + PLUGIN_FOLDER(plugin.getDataFolder(), null), + CONFIG_YAML(new File(plugin.getDataFolder()+File.separator + "config.yml"), new YamlConfiguration()), + LANG_YAML(new File(plugin.getDataFolder()+File.separator + "lang.yml"), new YamlConfiguration()); + + // Constructor, so we can assign the value we set here ^ to our File. + public File file; + public YamlConfiguration yaml; + FileType(File givenFile, YamlConfiguration yamlConfig) + { + file = givenFile; + yaml = yamlConfig; + } + } +} diff --git a/src/net/mindoverflow/network/uhccore/utils/LocalizedMessages.java b/src/net/mindoverflow/network/uhccore/utils/LocalizedMessages.java new file mode 100644 index 0000000..0e3095b --- /dev/null +++ b/src/net/mindoverflow/network/uhccore/utils/LocalizedMessages.java @@ -0,0 +1,18 @@ +package net.mindoverflow.network.uhccore.utils; + +public enum LocalizedMessages { + + INFO("info"), + PLAYER_POSITION("player_position"), + + WARNING_CONSOLE_ACCESS("error.console_access"), + + ERROR_CONSOLE_ACCESS_BLOCKED("error.console_access_blocked"); + + public String path; + + LocalizedMessages(String path) + { + this.path = path; + } +} diff --git a/src/net/mindoverflow/network/uhccore/utils/MessageUtils.java b/src/net/mindoverflow/network/uhccore/utils/MessageUtils.java new file mode 100644 index 0000000..59161f0 --- /dev/null +++ b/src/net/mindoverflow/network/uhccore/utils/MessageUtils.java @@ -0,0 +1,109 @@ +package net.mindoverflow.network.uhccore.utils; + + +import net.mindoverflow.network.uhccore.UhcCore; +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; +import org.bukkit.configuration.file.YamlConfiguration; + +import java.util.logging.Level; + +public class MessageUtils +{ + // Initialize the Debugger instance. + private static Debugger debugger = new Debugger(MessageUtils.class.getName()); + + + private static UhcCore plugin; + public MessageUtils(UhcCore plugin) + { + MessageUtils.plugin = plugin; + } + // Method to automatically load and send a localized message to the CommandSender. + public static void sendLocalizedMessage(String senderName, LocalizedMessages messageEnum) + { + // We are gonna need to know who to send the message to! + CommandSender sender; + // Check if the message is being sent by console. + if(senderName.equals("CONSOLE") && plugin.getServer().getPlayer(senderName) == null) + { + sender = plugin.getServer().getConsoleSender(); + } + else + { + sender = plugin.getServer().getPlayer(senderName); + } + + // If we actually have a sender, send it the message and color it! + if(sender != null) sender.sendMessage(getLocalizedMessage(messageEnum, true)); + // If the sender is null, report it to the debugger. + else debugger.sendDebugMessage(Level.SEVERE, "Sender is null!"); + } + + + // Method to send a colorized message to the CommandSender. + public static void sendColorizedMessage(String senderName, String message) + { + // We are gonna need to know who to send the message to! + CommandSender sender; + // Check if the message is being sent by console. + if (senderName.equals("CONSOLE") && plugin.getServer().getPlayer(senderName) == null) { + sender = plugin.getServer().getConsoleSender(); + } else { + sender = plugin.getServer().getPlayer(senderName); + } + + // If we actually have a sender, send it the message! + if(sender != null) sender.sendMessage(colorize(message)); + // If the sender is null, report it to the debugger. + else debugger.sendDebugMessage(Level.SEVERE, "Sender is null!"); + } + + public static String getLocalizedMessage(LocalizedMessages messageEnum, boolean applyColor) + { + + /* + Load the string from the enum. + We are doing this because we don't want random strings to be passed to this method: we want it done + this way and this way only, so we don't get any error as every entry added to the enum is manually + checked before actually adding it. + */ + String path = messageEnum.path; + + // Initialize the Lang file. + YamlConfiguration langFile = FileUtils.FileType.LANG_YAML.yaml; + + // Initialize the message string and store the String from the lang file to it. + String localizedMessage = langFile.getString(path); + + // Check if the message is null + if (localizedMessage != null) + { + // Check if we have to color the message or leave the symbols inside for further elaboration. + if(applyColor) + { + // Replace the famous '&' and '§' symbols with a ChatColor so we can color the messages! + localizedMessage = colorize(localizedMessage); + } + + } else + { + // Report if the message is null. + debugger.sendDebugMessage(Level.SEVERE, "String " + path + " is null!"); + } + // Return the message, whether it's colored, not colored or null (if it's null, it's the same as writing "return null"). + return localizedMessage; + } + + // Colorize Strings! + public static String colorize(String str) + { + /* + Since the translateAlternateColors method works with only one char and overwrites the previous one, + we are going to replace '&' with '§' and then run that method with all the '§'s. + */ + str = str.replace('&', '§'); + ChatColor.translateAlternateColorCodes('§', str); + return str; + } +} \ No newline at end of file diff --git a/src/net/mindoverflow/network/uhccore/utils/PermissionUtils.java b/src/net/mindoverflow/network/uhccore/utils/PermissionUtils.java new file mode 100644 index 0000000..654cafc --- /dev/null +++ b/src/net/mindoverflow/network/uhccore/utils/PermissionUtils.java @@ -0,0 +1,31 @@ +package net.mindoverflow.network.uhccore.utils; + +import net.mindoverflow.network.uhccore.UhcCore; +import org.bukkit.entity.Player; + +import java.util.logging.Level; + +public class PermissionUtils +{ + + // Initialize the Debugger instance. + private static Debugger debugger = new Debugger(PermissionUtils.class.getName()); + + + private static UhcCore plugin; + public PermissionUtils(UhcCore givenPlugin) { plugin = givenPlugin; } + + // Method to get the permission string from the Permissions enum. + public static boolean playerHasPermission(String username, Permissions permission) + { + debugger.sendDebugMessage(Level.INFO, "Permission: " + permission.permission + "; Player name is: " + username); + Player user = plugin.getServer().getPlayer(username); + { + if (user != null && user.hasPermission(permission.permission)) + { + return true; + } + } + return false; + } +} diff --git a/src/net/mindoverflow/network/uhccore/utils/Permissions.java b/src/net/mindoverflow/network/uhccore/utils/Permissions.java new file mode 100644 index 0000000..6c04ace --- /dev/null +++ b/src/net/mindoverflow/network/uhccore/utils/Permissions.java @@ -0,0 +1,10 @@ +package net.mindoverflow.network.uhccore.utils; + +public enum Permissions +{ + TEXTCOMPONENT_COMMAND("pluginname.command.textcomponent"); + + public String permission; + + Permissions(String permission) { this.permission = permission; } +} diff --git a/src/plugin.yml b/src/plugin.yml new file mode 100644 index 0000000..7d59277 --- /dev/null +++ b/src/plugin.yml @@ -0,0 +1,9 @@ +name: UHC-Core +version: BUILD_NUMBER +author: mind_overflow +api-version: '1.15' +main: net.mindoverflow.network.uhccore.UhcCore +commands: + uhc: + description: UHC-Core base command. + usage: /uhc \ No newline at end of file