This commit is contained in:
Mika Westphal 2025-01-26 17:14:30 +01:00
commit e817867af0
17 changed files with 499 additions and 0 deletions

119
.gitignore vendored Normal file
View File

@ -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

50
build.gradle Normal file
View File

@ -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
}
}

0
gradle.properties Normal file
View File

View File

@ -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

1
settings.gradle Normal file
View File

@ -0,0 +1 @@
rootProject.name = 'Survival Games'

View File

@ -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<String> 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);
}
}
}

View File

@ -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();
}

View File

@ -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 { }

View File

@ -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();
}

View File

@ -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;
}
}

View File

@ -0,0 +1,5 @@
package de.polyfish0.survivalGames.database;
public class Database {
}

View File

@ -0,0 +1,6 @@
package de.polyfish0.survivalGames.database;
public interface Table {
void setup();
void update();
}

View File

@ -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) {
}
}

View File

@ -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();
}

View File

@ -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<Player, Stack<GuiInterface>> interfaceHistory = new HashMap<>();
public static GuiManager getInstance() {
return INSTANCE;
}
public void openInventory(Player p, Class<? extends GuiInterface> guiInterface) {
try {
GuiInterface interfaceInstance = guiInterface.getDeclaredConstructor().newInstance();
if(!interfaceHistory.containsKey(p)) {
Stack<GuiInterface> 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<? extends GuiInterface> 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()));
}
}

View File

@ -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<ItemStack, Consumer<Player>> 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;
}
}

View File

@ -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