From 2987887e5c40253fb3f9f386d58f2c29e07d6cef Mon Sep 17 00:00:00 2001 From: Terry <68700354+teraprath@users.noreply.github.com> Date: Mon, 8 May 2023 12:33:05 +0200 Subject: [PATCH] ADD Module File Configurations --- pom.xml | 2 +- .../java/net/spigotcloud/lobby/Lobby.java | 77 ++++++++++ .../net/spigotcloud/lobby/api/LobbyAPI.java | 12 ++ .../lobby/command/BaseCommand.java | 79 ++++++++++ .../lobby/command/BuildCommand.java | 46 ++++++ .../lobby/command/ModulesCommand.java | 33 +++++ .../lobby/command/ReloadCommand.java | 30 ++++ .../spigotcloud/lobby/command/SubCommand.java | 23 +++ .../lobby/listener/JoinQuitListener.java | 35 +++++ .../lobby/listener/ProtectListener.java | 69 +++++++++ .../net/spigotcloud/lobby/module/Module.java | 66 +++++++++ .../lobby/module/ModuleDescriptionFile.java | 28 ++++ .../lobby/module/ModuleLoader.java | 135 ++++++++++++++++++ src/main/resources/plugin.yml | 13 ++ 14 files changed, 647 insertions(+), 1 deletion(-) create mode 100644 src/main/java/net/spigotcloud/lobby/Lobby.java create mode 100644 src/main/java/net/spigotcloud/lobby/api/LobbyAPI.java create mode 100644 src/main/java/net/spigotcloud/lobby/command/BaseCommand.java create mode 100644 src/main/java/net/spigotcloud/lobby/command/BuildCommand.java create mode 100644 src/main/java/net/spigotcloud/lobby/command/ModulesCommand.java create mode 100644 src/main/java/net/spigotcloud/lobby/command/ReloadCommand.java create mode 100644 src/main/java/net/spigotcloud/lobby/command/SubCommand.java create mode 100644 src/main/java/net/spigotcloud/lobby/listener/JoinQuitListener.java create mode 100644 src/main/java/net/spigotcloud/lobby/listener/ProtectListener.java create mode 100644 src/main/java/net/spigotcloud/lobby/module/Module.java create mode 100644 src/main/java/net/spigotcloud/lobby/module/ModuleDescriptionFile.java create mode 100644 src/main/java/net/spigotcloud/lobby/module/ModuleLoader.java create mode 100644 src/main/resources/plugin.yml diff --git a/pom.xml b/pom.xml index f951a42..2d7a1ed 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ net.spigotcloud lobby - 1.2.3-SNAPSHOT + 1.2.5-SNAPSHOT jar Lobby diff --git a/src/main/java/net/spigotcloud/lobby/Lobby.java b/src/main/java/net/spigotcloud/lobby/Lobby.java new file mode 100644 index 0000000..18433de --- /dev/null +++ b/src/main/java/net/spigotcloud/lobby/Lobby.java @@ -0,0 +1,77 @@ +package net.spigotcloud.lobby; + +import net.spigotcloud.lobby.api.LobbyAPI; +import net.spigotcloud.lobby.command.BaseCommand; +import net.spigotcloud.lobby.command.BuildCommand; +import net.spigotcloud.lobby.command.ModulesCommand; +import net.spigotcloud.lobby.command.ReloadCommand; +import net.spigotcloud.lobby.listener.JoinQuitListener; +import net.spigotcloud.lobby.listener.ProtectListener; +import net.spigotcloud.lobby.module.ModuleLoader; +import org.bukkit.entity.Player; +import org.bukkit.plugin.PluginManager; +import org.bukkit.plugin.java.JavaPlugin; + +import java.util.HashSet; +import java.util.Set; + +public final class Lobby extends JavaPlugin { + + private static Lobby instance; + private final BaseCommand command = new BaseCommand(); + private final Set buildPlayers = new HashSet<>(); + private ModuleLoader moduleLoader; + + @Override + public void onEnable() { + + instance = this; + + this.moduleLoader = new ModuleLoader(); + + moduleLoader.reload(); + moduleLoader.enable(); + + registerCommands(); + registerEvents(); + + + } + + private void registerCommands() { + getCommand("lobby").setExecutor(this.command); + command.registerSubCommand("reload", new ReloadCommand()); + command.registerSubCommand("modules", new ModulesCommand()); + command.registerSubCommand("build", new BuildCommand()); + } + + private void registerEvents() { + final PluginManager pm = getServer().getPluginManager(); + pm.registerEvents(new JoinQuitListener(), this); + pm.registerEvents(new ProtectListener(), this); + } + + @Override + public void onDisable() { + moduleLoader.disable(); + } + + public BaseCommand getBaseCommand() { + return this.command; + } + + + public ModuleLoader getModuleLoader() { + return this.moduleLoader; + } + + public Set getBuildPlayers() { + return this.buildPlayers; + } + + public static Lobby getInstance() { + return instance; + } + + +} diff --git a/src/main/java/net/spigotcloud/lobby/api/LobbyAPI.java b/src/main/java/net/spigotcloud/lobby/api/LobbyAPI.java new file mode 100644 index 0000000..26888ab --- /dev/null +++ b/src/main/java/net/spigotcloud/lobby/api/LobbyAPI.java @@ -0,0 +1,12 @@ +package net.spigotcloud.lobby.api; + +import org.bukkit.Bukkit; +import org.bukkit.plugin.Plugin; + +public class LobbyAPI { + + public static Plugin getPlugin() { + return Bukkit.getServer().getPluginManager().getPlugin("Lobby"); + } + +} diff --git a/src/main/java/net/spigotcloud/lobby/command/BaseCommand.java b/src/main/java/net/spigotcloud/lobby/command/BaseCommand.java new file mode 100644 index 0000000..6ba6710 --- /dev/null +++ b/src/main/java/net/spigotcloud/lobby/command/BaseCommand.java @@ -0,0 +1,79 @@ +package net.spigotcloud.lobby.command; + +import net.spigotcloud.lobby.Lobby; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.command.TabCompleter; +import org.bukkit.plugin.PluginDescriptionFile; + +import javax.annotation.Nonnull; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +// TODO: Custom messages + +public class BaseCommand implements CommandExecutor, TabCompleter { + + private final HashMap subCommands; + + public BaseCommand() { + this.subCommands = new HashMap<>(); + } + + public void registerSubCommand(@Nonnull String command, @Nonnull SubCommand subCommand) { + this.subCommands.put(command, subCommand); + } + + public void unregister(@Nonnull String command) { + this.subCommands.remove(command); + } + + + @Override + public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + + if (args.length > 0) { + + if (subCommands.containsKey(args[0])) { + SubCommand subCommand = subCommands.get(args[0]); + if (sender.hasPermission(subCommand.getPermission())) { + subCommand.onCommand(sender, command, label, args); + } else { + sender.sendMessage("No permission."); + } + } else { + sender.sendMessage("Sub-Command does not exists."); + } + + } else { + PluginDescriptionFile desc = Lobby.getInstance().getDescription(); + sender.sendMessage(desc.getName() + " v" + desc.getVersion() + " by " + desc.getAuthors().get(0)); + } + + return false; + } + + @Override + public List onTabComplete(CommandSender sender, Command command, String label, String[] args) { + + ArrayList list = new ArrayList<>(); + String current = args[args.length - 1].toLowerCase(); + + + if (args.length == 1) { + subCommands.forEach(((s, subCommand) -> { + list.add(s.toLowerCase()); + })); + } else { + SubCommand subCommand = subCommands.get(args[0]); + if (subCommand != null) { + return subCommand.onTabComplete(sender, command, label, args); + } + } + + list.removeIf(s -> !s.toLowerCase().startsWith(current)); + return list; + } +} diff --git a/src/main/java/net/spigotcloud/lobby/command/BuildCommand.java b/src/main/java/net/spigotcloud/lobby/command/BuildCommand.java new file mode 100644 index 0000000..8e1d72e --- /dev/null +++ b/src/main/java/net/spigotcloud/lobby/command/BuildCommand.java @@ -0,0 +1,46 @@ +package net.spigotcloud.lobby.command; + +import net.spigotcloud.lobby.Lobby; +import org.bukkit.GameMode; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import java.util.List; + +// TODO: Custom messages + +public class BuildCommand extends SubCommand { + + public BuildCommand() { + super("build"); + } + + @Override + public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + + if (!(sender instanceof Player)) { + // TODO: Send message to console + return false; + } + + final Player player = (Player) sender; + + if (Lobby.getInstance().getBuildPlayers().contains(player)) { + Lobby.getInstance().getBuildPlayers().remove(player); + player.setGameMode(GameMode.SURVIVAL); + player.sendMessage("Build Mode: off"); + } else { + Lobby.getInstance().getBuildPlayers().add(player); + player.setGameMode(GameMode.CREATIVE); + player.sendMessage("Build Mode: on"); + } + + return false; + } + + @Override + public List onTabComplete(CommandSender sender, Command command, String label, String[] args) { + return null; + } +} diff --git a/src/main/java/net/spigotcloud/lobby/command/ModulesCommand.java b/src/main/java/net/spigotcloud/lobby/command/ModulesCommand.java new file mode 100644 index 0000000..d6f60e7 --- /dev/null +++ b/src/main/java/net/spigotcloud/lobby/command/ModulesCommand.java @@ -0,0 +1,33 @@ +package net.spigotcloud.lobby.command; + +// TODO: Custom messages + +import net.spigotcloud.lobby.Lobby; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; + +import java.util.List; + +public class ModulesCommand extends SubCommand { + + public ModulesCommand() { + super("modules"); + } + + @Override + public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + sender.sendMessage(""); + sender.sendMessage("§6§lLobby Modules"); + Lobby.getInstance().getModuleLoader().getModules().forEach(module -> { + sender.sendMessage("§8- §7" + module.getDescriptionFile().getName() + " v" + module.getDescriptionFile().getVersion() + " by " + module.getDescriptionFile().getAuthor()); + }); + return false; + } + + @Override + public List onTabComplete(CommandSender sender, Command command, String label, String[] args) { + return null; + } + +} + diff --git a/src/main/java/net/spigotcloud/lobby/command/ReloadCommand.java b/src/main/java/net/spigotcloud/lobby/command/ReloadCommand.java new file mode 100644 index 0000000..db4ce88 --- /dev/null +++ b/src/main/java/net/spigotcloud/lobby/command/ReloadCommand.java @@ -0,0 +1,30 @@ +package net.spigotcloud.lobby.command; + +import net.spigotcloud.lobby.Lobby; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; + +import java.util.List; + +// TODO: Custom messages + +public class ReloadCommand extends SubCommand { + + public ReloadCommand() { + super("reload"); + } + + @Override + public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + sender.sendMessage("Reloading modules and files..."); + Lobby.getInstance().getModuleLoader().reload(); + sender.sendMessage("Lobby reload successfully."); + return false; + } + + @Override + public List onTabComplete(CommandSender sender, Command command, String label, String[] args) { + return null; + } + +} diff --git a/src/main/java/net/spigotcloud/lobby/command/SubCommand.java b/src/main/java/net/spigotcloud/lobby/command/SubCommand.java new file mode 100644 index 0000000..cada2dc --- /dev/null +++ b/src/main/java/net/spigotcloud/lobby/command/SubCommand.java @@ -0,0 +1,23 @@ +package net.spigotcloud.lobby.command; + +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; + +import java.util.List; + +public abstract class SubCommand { + + private final String permission; + + public SubCommand(String permission) { + this.permission = permission; + } + + public abstract boolean onCommand(CommandSender sender, Command command, String label, String[] args); + public abstract List onTabComplete(CommandSender sender, Command command, String label, String[] args); + + public String getPermission() { + return "lobby.command." + this.permission; + } + +} diff --git a/src/main/java/net/spigotcloud/lobby/listener/JoinQuitListener.java b/src/main/java/net/spigotcloud/lobby/listener/JoinQuitListener.java new file mode 100644 index 0000000..984ce60 --- /dev/null +++ b/src/main/java/net/spigotcloud/lobby/listener/JoinQuitListener.java @@ -0,0 +1,35 @@ +package net.spigotcloud.lobby.listener; + +// TODO: Custom join messages + +import net.spigotcloud.lobby.Lobby; +import org.bukkit.GameMode; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.event.player.PlayerQuitEvent; + +public class JoinQuitListener implements Listener { + + @EventHandler + public void onPlayerJoin(PlayerJoinEvent e) { + final Player player = e.getPlayer(); + e.setJoinMessage(null); + player.getInventory().clear(); + player.setHealth(20); + player.setFoodLevel(20); + player.setExp(0); + player.setTotalExperience(0); + player.setLevel(0); + player.setGameMode(GameMode.SURVIVAL); + } + + @EventHandler + public void onPlayerQuit(PlayerQuitEvent e) { + final Player player = e.getPlayer(); + e.setQuitMessage(null); + Lobby.getInstance().getBuildPlayers().remove(player); + } + +} diff --git a/src/main/java/net/spigotcloud/lobby/listener/ProtectListener.java b/src/main/java/net/spigotcloud/lobby/listener/ProtectListener.java new file mode 100644 index 0000000..64538b7 --- /dev/null +++ b/src/main/java/net/spigotcloud/lobby/listener/ProtectListener.java @@ -0,0 +1,69 @@ +package net.spigotcloud.lobby.listener; + +import net.spigotcloud.lobby.Lobby; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +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.EntityDamageEvent; +import org.bukkit.event.entity.FoodLevelChangeEvent; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.player.PlayerDropItemEvent; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.event.player.PlayerSwapHandItemsEvent; + +import javax.annotation.Nonnull; + +public class ProtectListener implements Listener { + + @EventHandler + public void onPlayerDamage(EntityDamageEvent e) { + if (e.getEntity() instanceof Player) { + e.setCancelled(true); + } + } + + @EventHandler + public void onBlockBreak(BlockBreakEvent e) { + protectEvent(e, true, e.getPlayer()); + } + + @EventHandler + public void onBlockPlace(BlockPlaceEvent e) { + protectEvent(e, true, e.getPlayer()); + } + + @EventHandler + public void onItemDrop(PlayerDropItemEvent e) { + protectEvent(e, true, e.getPlayer()); + } + + @EventHandler + public void onInventoryClick(InventoryClickEvent e) { + protectEvent(e, true, (Player) e.getWhoClicked()); + } + + @EventHandler + public void onInteract(PlayerInteractEvent e) { + protectEvent(e, true, e.getPlayer()); + } + + @EventHandler + public void onFoodLevelChange(FoodLevelChangeEvent e) { + protectEvent(e, false, null); + } + + @EventHandler + public void onItemSwap(PlayerSwapHandItemsEvent e) { + protectEvent(e, true, e.getPlayer()); + } + + private void protectEvent(@Nonnull Cancellable event, boolean bypass, Player player) { + if (!Lobby.getInstance().getBuildPlayers().contains(player)) { + event.setCancelled(true); + } + } + +} diff --git a/src/main/java/net/spigotcloud/lobby/module/Module.java b/src/main/java/net/spigotcloud/lobby/module/Module.java new file mode 100644 index 0000000..0ae9496 --- /dev/null +++ b/src/main/java/net/spigotcloud/lobby/module/Module.java @@ -0,0 +1,66 @@ +package net.spigotcloud.lobby.module; + +import net.spigotcloud.lobby.api.LobbyAPI; +import net.spigotcloud.lobby.command.SubCommand; +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.event.Listener; + +import javax.annotation.Nonnull; +import java.io.File; +import java.io.IOException; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +public abstract class Module { + + private final Set listeners = new HashSet<>(); + private final Map subCommands = new HashMap<>(); + private ModuleDescriptionFile descriptionFile; + private File file; + private FileConfiguration config; + + public void init(@Nonnull ModuleDescriptionFile moduleDescriptionFile) { + this.descriptionFile = moduleDescriptionFile; + this.file = new File(LobbyAPI.getPlugin().getDataFolder(), "modules/" + this.descriptionFile.getName()); + this.config = YamlConfiguration.loadConfiguration(this.file); + } + + public FileConfiguration getConfig() { + return this.config; + } + + public void saveConfig() { + try { + this.config.save(file); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public abstract void onEnable(); + public abstract void onDisable(); + + public void registerListener(@Nonnull Listener listener) { + this.listeners.add(listener); + } + + public Set getListeners() { + return this.listeners; + } + + public void registerSubCommand(@Nonnull String command, @Nonnull SubCommand subCommand) { + this.subCommands.put(command, subCommand); + } + + public Map getSubCommands() { + return this.subCommands; + } + + public ModuleDescriptionFile getDescriptionFile() { + return descriptionFile; + } + +} diff --git a/src/main/java/net/spigotcloud/lobby/module/ModuleDescriptionFile.java b/src/main/java/net/spigotcloud/lobby/module/ModuleDescriptionFile.java new file mode 100644 index 0000000..4d74343 --- /dev/null +++ b/src/main/java/net/spigotcloud/lobby/module/ModuleDescriptionFile.java @@ -0,0 +1,28 @@ +package net.spigotcloud.lobby.module; + +public class ModuleDescriptionFile { + + private final String name; + private final String author; + private final String version; + + + public ModuleDescriptionFile(String name, String author, String version) { + this.name = name; + this.author = author; + this.version = version; + } + + public String getName() { + return name; + } + + public String getAuthor() { + return author; + } + + public String getVersion() { + return version; + } + +} diff --git a/src/main/java/net/spigotcloud/lobby/module/ModuleLoader.java b/src/main/java/net/spigotcloud/lobby/module/ModuleLoader.java new file mode 100644 index 0000000..e46b02c --- /dev/null +++ b/src/main/java/net/spigotcloud/lobby/module/ModuleLoader.java @@ -0,0 +1,135 @@ +package net.spigotcloud.lobby.module; + +import net.spigotcloud.lobby.Lobby; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.event.HandlerList; + +import java.io.*; +import java.net.URL; +import java.net.URLClassLoader; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.logging.Level; +import java.util.zip.ZipFile; + +public class ModuleLoader { + + private final Set modules = new HashSet<>(); + private final Map, ModuleDescriptionFile> classes = new HashMap(); + private final File file; + + public ModuleLoader() { + + this.file = new File(Lobby.getInstance().getDataFolder(), "modules"); + if (!file.exists()) { + file.mkdir(); + } + + + } + + + public void load() { + + if (file.exists() && file.isDirectory()) { + + this.classes.clear(); + + File[] files = file.listFiles(new FilenameFilter() { + @Override + public boolean accept(File dir, String name) { + return name.endsWith(".jar"); + } + }); + + for (File jar : files) { + String mainClass = null; + try { + ZipFile zipFile = new ZipFile(jar); + + InputStream is = zipFile.getInputStream(zipFile.getEntry("module.yml")); + + YamlConfiguration config = YamlConfiguration.loadConfiguration(new InputStreamReader(is)); + mainClass = config.getString("main"); + + String name = config.getString("name"); + String author = config.getString("author"); + String version = config.getString("version"); + + if (mainClass == null || name == null || version == null) { + Lobby.getInstance().getLogger().log(Level.SEVERE, "Error while loading module file " + jar.getName() + " (Please check 'module.yml' file in Module"); + return; + } + + + ClassLoader l = URLClassLoader.newInstance(new URL[]{jar.toURI().toURL()}, getClass().getClassLoader()); + + Class clazz = l.loadClass(mainClass); + classes.put(clazz, new ModuleDescriptionFile(name, author != null ? author : "Unknown", version)); + + } catch (IOException e) { + Lobby.getInstance().getLogger().log(Level.SEVERE, "Error while loading module file " + jar.getName()); + e.printStackTrace(); + } catch (ClassNotFoundException e) { + Lobby.getInstance().getLogger().log(Level.SEVERE, "Class not found! Wrong main defined in module.yml?: " + jar.getName() + " class: " + mainClass); + e.printStackTrace(); + } + + + } + + + } + } + + public void enable() { + this.classes.forEach((clazz, desc) -> { + try { + Object object = clazz.newInstance(); + + if (object instanceof Module) { + Module module = (Module) object; + module.init(desc); + module.onEnable(); + module.getListeners().forEach(listener -> { + Lobby.getInstance().getServer().getPluginManager().registerEvents(listener, Lobby.getInstance()); + }); + module.getSubCommands().forEach(((s, subCommand) -> { + Lobby.getInstance().getBaseCommand().registerSubCommand(s, subCommand); + })); + modules.add(module); + Lobby.getInstance().getLogger().log(Level.INFO, "Enabled: Module " + desc.getName() + " v" + desc.getVersion() + " by " + desc.getAuthor()); + } + } catch (InstantiationException | IllegalAccessException e) { + e.printStackTrace(); + } + }); + } + + public void disable() { + this.modules.clear(); + for (Module module : modules) { + module.onDisable(); + module.getListeners().forEach(HandlerList::unregisterAll); + module.getSubCommands().forEach(((s, subCommand) -> { + Lobby.getInstance().getBaseCommand().unregister(s); + })); + Lobby.getInstance().getLogger().log(Level.INFO, "Disabled: Module " + module.getDescriptionFile().getName() + " v" + module.getDescriptionFile().getVersion() + " by " + module.getDescriptionFile().getAuthor()); + + } + } + + public Set getModules() { + return this.modules; + } + + public void reload() { + disable(); + load(); + enable(); + } + + +} diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml new file mode 100644 index 0000000..6d699a8 --- /dev/null +++ b/src/main/resources/plugin.yml @@ -0,0 +1,13 @@ +name: Lobby +version: '${project.version}' +main: net.spigotcloud.lobby.Lobby +api-version: 1.19 +softdepend: [ PointsAPI ] +authors: [ TerryGHG ] +description: Modular Lobby Plugin for Spigot 1.19+ +website: https://github.com/teraprath +commands: + lobby: + description: Base Command + permission: lobby.command + aliases: [ l, lb, hub ]