From e817867af0b55589cbb01b6f40971ae5ff986f73 Mon Sep 17 00:00:00 2001 From: Mika Westphal Date: Sun, 26 Jan 2025 17:14:30 +0100 Subject: [PATCH] f --- .gitignore | 119 ++++++++++++++++++ build.gradle | 50 ++++++++ gradle.properties | 0 gradle/wrapper/gradle-wrapper.properties | 7 ++ settings.gradle | 1 + .../survivalGames/SurvivalGames.java | 88 +++++++++++++ .../survivalGames/annotations/Command.java | 12 ++ .../survivalGames/annotations/EventClass.java | 10 ++ .../survivalGames/annotations/Permission.java | 12 ++ .../commands/SurvivalGamesCommand.java | 25 ++++ .../survivalGames/database/Database.java | 5 + .../survivalGames/database/Table.java | 6 + .../events/ChestGuiInteractionEvent.java | 14 +++ .../survivalGames/gui/GuiInterface.java | 10 ++ .../survivalGames/gui/GuiManager.java | 58 +++++++++ .../survivalGames/gui/menus/MainMenu.java | 74 +++++++++++ src/main/resources/plugin.yml | 8 ++ 17 files changed, 499 insertions(+) create mode 100644 .gitignore create mode 100644 build.gradle create mode 100644 gradle.properties create mode 100644 gradle/wrapper/gradle-wrapper.properties create mode 100644 settings.gradle create mode 100644 src/main/java/de/polyfish0/survivalGames/SurvivalGames.java create mode 100644 src/main/java/de/polyfish0/survivalGames/annotations/Command.java create mode 100644 src/main/java/de/polyfish0/survivalGames/annotations/EventClass.java create mode 100644 src/main/java/de/polyfish0/survivalGames/annotations/Permission.java create mode 100644 src/main/java/de/polyfish0/survivalGames/commands/SurvivalGamesCommand.java create mode 100644 src/main/java/de/polyfish0/survivalGames/database/Database.java create mode 100644 src/main/java/de/polyfish0/survivalGames/database/Table.java create mode 100644 src/main/java/de/polyfish0/survivalGames/events/ChestGuiInteractionEvent.java create mode 100644 src/main/java/de/polyfish0/survivalGames/gui/GuiInterface.java create mode 100644 src/main/java/de/polyfish0/survivalGames/gui/GuiManager.java create mode 100644 src/main/java/de/polyfish0/survivalGames/gui/menus/MainMenu.java create mode 100644 src/main/resources/plugin.yml diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d5f737e --- /dev/null +++ b/.gitignore @@ -0,0 +1,119 @@ +# User-specific stuff +.idea/ + +*.iml +*.ipr +*.iws + +# IntelliJ +out/ +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Compiled class file +*.class + +# Log file +*.log + +# BlueJ files +*.ctxt + +# Package Files # +*.jar +*.war +*.nar +*.ear +*.zip +*.tar.gz +*.rar + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* + +*~ + +# temporary files which can be created if a process still has a handle open of a deleted file +.fuse_hidden* + +# KDE directory preferences +.directory + +# Linux trash folder which might appear on any partition or disk +.Trash-* + +# .nfs files are created when an open file is removed but is still being accessed +.nfs* + +# General +.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + +# Thumbnails +._* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +# Windows thumbnail cache files +Thumbs.db +Thumbs.db:encryptable +ehthumbs.db +ehthumbs_vista.db + +# Dump file +*.stackdump + +# Folder config file +[Dd]esktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Windows Installer files +*.cab +*.msi +*.msix +*.msm +*.msp + +# Windows shortcuts +*.lnk + +.gradle +build/ + +# Ignore Gradle GUI config +gradle-app.setting + +# Cache of project +.gradletasknamecache + +**/build/ + +# Common working directory +run/ +runs/ + +# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored) +!gradle-wrapper.jar diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000..e37f0c3 --- /dev/null +++ b/build.gradle @@ -0,0 +1,50 @@ +plugins { + id 'java' +} + +group = 'de.polyfish0' +version = '1.0-SNAPSHOT' + +repositories { + mavenCentral() + maven { + name = "spigotmc-repo" + url = "https://hub.spigotmc.org/nexus/content/repositories/snapshots/" + } + maven { + name = "sonatype" + url = "https://oss.sonatype.org/content/groups/public/" + } +} + +dependencies { + compileOnly("org.spigotmc:spigot-api:1.21.3-R0.1-SNAPSHOT") + implementation("org.xerial:sqlite-jdbc:3.48.0.0") +} + +def targetJavaVersion = 21 +java { + def javaVersion = JavaVersion.toVersion(targetJavaVersion) + sourceCompatibility = javaVersion + targetCompatibility = javaVersion + if (JavaVersion.current() < javaVersion) { + toolchain.languageVersion = JavaLanguageVersion.of(targetJavaVersion) + } +} + +tasks.withType(JavaCompile).configureEach { + options.encoding = 'UTF-8' + + if (targetJavaVersion >= 10 || JavaVersion.current().isJava10Compatible()) { + options.release.set(targetJavaVersion) + } +} + +processResources { + def props = [version: version] + inputs.properties props + filteringCharset 'UTF-8' + filesMatching('plugin.yml') { + expand props + } +} diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 0000000..e69de29 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..9355b41 --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,7 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-8.10-bin.zip +networkTimeout=10000 +validateDistributionUrl=true +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/settings.gradle b/settings.gradle new file mode 100644 index 0000000..47e7026 --- /dev/null +++ b/settings.gradle @@ -0,0 +1 @@ +rootProject.name = 'Survival Games' diff --git a/src/main/java/de/polyfish0/survivalGames/SurvivalGames.java b/src/main/java/de/polyfish0/survivalGames/SurvivalGames.java new file mode 100644 index 0000000..db61ac8 --- /dev/null +++ b/src/main/java/de/polyfish0/survivalGames/SurvivalGames.java @@ -0,0 +1,88 @@ +package de.polyfish0.survivalGames; + +import com.google.common.reflect.ClassPath; +import de.polyfish0.survivalGames.annotations.Command; +import de.polyfish0.survivalGames.annotations.EventClass; +import de.polyfish0.survivalGames.annotations.Permission; +import org.bukkit.command.CommandExecutor; +import org.bukkit.event.Listener; +import org.bukkit.plugin.java.JavaPlugin; + +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; +import java.util.HashSet; +import java.util.Set; +import java.util.logging.Level; +import java.util.logging.Logger; + +public final class SurvivalGames extends JavaPlugin { + public static final Logger logger = Logger.getLogger("Survival Games"); + public static JavaPlugin plugin; + private final Set usedCommands = new HashSet<>(); + + @Override + public void onEnable() { + plugin = this; + + try { + ClassPath cp = ClassPath.from(getClass().getClassLoader()); + + for(ClassPath.ClassInfo ci : cp.getTopLevelClassesRecursive("de.polyfish0.survivalGames")) { + Class klass = ci.load(); + + if(klass.isAnnotationPresent(Command.class)) + registerCommand(klass); + + if(klass.isAnnotationPresent(EventClass.class)) + registerEvents(klass); + } + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + private void registerCommand(Class klass) { + if(!CommandExecutor.class.isAssignableFrom(klass)) { + logger.log(Level.SEVERE, "Class \"" + klass.getName() + "\" is annotated with @Command but does not implements CommandExecutor"); + return; + } + + final String commandName = klass.getAnnotation(Command.class).command(); + final String permission = klass.isAnnotationPresent(Permission.class) ? klass.getAnnotation(Permission.class).permission() : null; + + if (commandName == null || commandName.isEmpty()) { + logger.log(Level.SEVERE, "Command in class \"" + klass.getName() + "\" has an empty name!"); + return; + } + + if(usedCommands.contains(commandName)) { + logger.log(Level.SEVERE, "Command \"" + commandName + "\" is already in use by this plugin"); + return; + } + + try { + CommandExecutor commandExecutor = (CommandExecutor) klass.getDeclaredConstructor().newInstance(); + getCommand(commandName).setExecutor(commandExecutor); + + if(permission != null) + getCommand(commandName).setPermission(permission); + + usedCommands.add(klass.getAnnotation(Command.class).command()); + } catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException e) { + throw new RuntimeException(e); + } + } + + private void registerEvents(Class klass) { + if(!Listener.class.isAssignableFrom(klass)) { + logger.log(Level.SEVERE, "Class \"" + klass.getName() + "\" does not implements Listener but has the @EventClass annotation"); + return; + } + + try { + getServer().getPluginManager().registerEvents((Listener) klass.getDeclaredConstructor().newInstance(), this); + } catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException e) { + throw new RuntimeException(e); + } + } +} diff --git a/src/main/java/de/polyfish0/survivalGames/annotations/Command.java b/src/main/java/de/polyfish0/survivalGames/annotations/Command.java new file mode 100644 index 0000000..2a6003e --- /dev/null +++ b/src/main/java/de/polyfish0/survivalGames/annotations/Command.java @@ -0,0 +1,12 @@ +package de.polyfish0.survivalGames.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +public @interface Command { + String command(); +} \ No newline at end of file diff --git a/src/main/java/de/polyfish0/survivalGames/annotations/EventClass.java b/src/main/java/de/polyfish0/survivalGames/annotations/EventClass.java new file mode 100644 index 0000000..fbb52b8 --- /dev/null +++ b/src/main/java/de/polyfish0/survivalGames/annotations/EventClass.java @@ -0,0 +1,10 @@ +package de.polyfish0.survivalGames.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +public @interface EventClass { } \ No newline at end of file diff --git a/src/main/java/de/polyfish0/survivalGames/annotations/Permission.java b/src/main/java/de/polyfish0/survivalGames/annotations/Permission.java new file mode 100644 index 0000000..3982e44 --- /dev/null +++ b/src/main/java/de/polyfish0/survivalGames/annotations/Permission.java @@ -0,0 +1,12 @@ +package de.polyfish0.survivalGames.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +public @interface Permission { + String permission(); +} \ No newline at end of file diff --git a/src/main/java/de/polyfish0/survivalGames/commands/SurvivalGamesCommand.java b/src/main/java/de/polyfish0/survivalGames/commands/SurvivalGamesCommand.java new file mode 100644 index 0000000..cb9a432 --- /dev/null +++ b/src/main/java/de/polyfish0/survivalGames/commands/SurvivalGamesCommand.java @@ -0,0 +1,25 @@ +package de.polyfish0.survivalGames.commands; + +import de.polyfish0.survivalGames.annotations.Command; +import de.polyfish0.survivalGames.annotations.Permission; +import de.polyfish0.survivalGames.gui.GuiManager; +import de.polyfish0.survivalGames.gui.menus.MainMenu; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +@Command(command = "sg") +@Permission(permission = "survivalgames.admin") +public class SurvivalGamesCommand implements CommandExecutor { + @Override + public boolean onCommand(CommandSender sender, org.bukkit.command.Command command, String label, String[] args) { + if(!(sender instanceof Player)) { + sender.sendMessage("[Survival Games] You has to be a player to use this command!"); + return true; + } + + GuiManager.getInstance().openNewInventory((Player) sender, MainMenu.class); + + return true; + } +} diff --git a/src/main/java/de/polyfish0/survivalGames/database/Database.java b/src/main/java/de/polyfish0/survivalGames/database/Database.java new file mode 100644 index 0000000..e0e5288 --- /dev/null +++ b/src/main/java/de/polyfish0/survivalGames/database/Database.java @@ -0,0 +1,5 @@ +package de.polyfish0.survivalGames.database; + +public class Database { + +} diff --git a/src/main/java/de/polyfish0/survivalGames/database/Table.java b/src/main/java/de/polyfish0/survivalGames/database/Table.java new file mode 100644 index 0000000..6ac6700 --- /dev/null +++ b/src/main/java/de/polyfish0/survivalGames/database/Table.java @@ -0,0 +1,6 @@ +package de.polyfish0.survivalGames.database; + +public interface Table { + void setup(); + void update(); +} diff --git a/src/main/java/de/polyfish0/survivalGames/events/ChestGuiInteractionEvent.java b/src/main/java/de/polyfish0/survivalGames/events/ChestGuiInteractionEvent.java new file mode 100644 index 0000000..6a6c408 --- /dev/null +++ b/src/main/java/de/polyfish0/survivalGames/events/ChestGuiInteractionEvent.java @@ -0,0 +1,14 @@ +package de.polyfish0.survivalGames.events; + +import de.polyfish0.survivalGames.annotations.EventClass; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.inventory.InventoryClickEvent; + +@EventClass +public class ChestGuiInteractionEvent implements Listener { + @EventHandler + public void onUserInteractWithChestGuiEvent(InventoryClickEvent e) { + + } +} \ No newline at end of file diff --git a/src/main/java/de/polyfish0/survivalGames/gui/GuiInterface.java b/src/main/java/de/polyfish0/survivalGames/gui/GuiInterface.java new file mode 100644 index 0000000..c122320 --- /dev/null +++ b/src/main/java/de/polyfish0/survivalGames/gui/GuiInterface.java @@ -0,0 +1,10 @@ +package de.polyfish0.survivalGames.gui; + +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.InventoryView; + +public interface GuiInterface { + void setInventoryView(InventoryView view); + Inventory getInventory(); + InventoryView getInventoryView(); +} diff --git a/src/main/java/de/polyfish0/survivalGames/gui/GuiManager.java b/src/main/java/de/polyfish0/survivalGames/gui/GuiManager.java new file mode 100644 index 0000000..4bdc4aa --- /dev/null +++ b/src/main/java/de/polyfish0/survivalGames/gui/GuiManager.java @@ -0,0 +1,58 @@ +package de.polyfish0.survivalGames.gui; + +import org.bukkit.entity.Player; + +import java.lang.reflect.InvocationTargetException; +import java.util.EmptyStackException; +import java.util.HashMap; +import java.util.Stack; + +public class GuiManager { + private final static GuiManager INSTANCE = new GuiManager(); + private final HashMap> interfaceHistory = new HashMap<>(); + + public static GuiManager getInstance() { + return INSTANCE; + } + + public void openInventory(Player p, Class guiInterface) { + try { + GuiInterface interfaceInstance = guiInterface.getDeclaredConstructor().newInstance(); + + if(!interfaceHistory.containsKey(p)) { + Stack stack = new Stack<>(); + stack.push(interfaceInstance); + + interfaceHistory.put(p, stack); + }else { + interfaceHistory.get(p).push(interfaceInstance); + } + + interfaceInstance.setInventoryView(p.openInventory(interfaceInstance.getInventory())); + } catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException e) { + throw new RuntimeException(e); + } + } + + public void openNewInventory(Player p, Class guiInterface) { + if(interfaceHistory.containsKey(p)) { + p.closeInventory(); + interfaceHistory.remove(p); + } + + openInventory(p, guiInterface); + } + + public void popInventory(Player p) { + GuiInterface lastInterface; + try { + lastInterface = interfaceHistory.get(p).pop(); + } catch (EmptyStackException e) { + p.closeInventory(); + return; + } + + p.closeInventory(); + lastInterface.setInventoryView(p.openInventory(lastInterface.getInventory())); + } +} diff --git a/src/main/java/de/polyfish0/survivalGames/gui/menus/MainMenu.java b/src/main/java/de/polyfish0/survivalGames/gui/menus/MainMenu.java new file mode 100644 index 0000000..e895885 --- /dev/null +++ b/src/main/java/de/polyfish0/survivalGames/gui/menus/MainMenu.java @@ -0,0 +1,74 @@ +package de.polyfish0.survivalGames.gui.menus; + +import de.polyfish0.survivalGames.annotations.EventClass; +import de.polyfish0.survivalGames.gui.GuiInterface; +import de.polyfish0.survivalGames.gui.GuiManager; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.InventoryView; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +import java.util.HashMap; +import java.util.UUID; +import java.util.function.Consumer; + +@EventClass +public class MainMenu implements GuiInterface, Listener { + private Inventory inventory; + private final HashMap> methodRegister = new HashMap<>(); + private InventoryView inventoryView; + + @Override + public Inventory getInventory() { + if(inventory != null) + return inventory; + + inventory = Bukkit.createInventory(null, 18); + + ItemStack backButton = new ItemStack(Material.RED_STAINED_GLASS_PANE, 1); + + ItemMeta meta = backButton.getItemMeta(); + meta.setDisplayName("Back Button"); + backButton.setItemMeta(meta); + + inventory.addItem(backButton); + + methodRegister.put(backButton, GuiManager.getInstance()::popInventory); + + for(int i = 1; i <= 8; i++) + inventory.setItem(i, new ItemStack(Material.GRAY_STAINED_GLASS_PANE)); + + return inventory; + } + + @EventHandler + public void onClick(InventoryClickEvent e) { + if(e.getClickedInventory() != inventoryView.getInventory(0)) + return; + + if(!methodRegister.containsKey(e.getCurrentItem())) { + e.setCancelled(true); + return; + } + + methodRegister.get(e.getCurrentItem()).accept(Bukkit.getPlayer(e.getWhoClicked().getName())); + } + + @Override + public void setInventoryView(InventoryView view) { + inventoryView = view; + System.out.println(view); + System.out.println(inventoryView); + } + + @Override + public InventoryView getInventoryView() { + return inventoryView; + } +} diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml new file mode 100644 index 0000000..5036a25 --- /dev/null +++ b/src/main/resources/plugin.yml @@ -0,0 +1,8 @@ +name: survivalGames +version: '1.0-SNAPSHOT' +main: de.polyfish0.survivalGames.SurvivalGames +api-version: '1.21' +commands: + sg: + usage: /sg + description: Main command for Survival Games \ No newline at end of file