diff --git a/build.gradle.kts b/build.gradle.kts index 87e5b1d..cdf6c3d 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -4,11 +4,13 @@ import org.gradle.kotlin.dsl.provideDelegate /* ------------------------------ Plugins ------------------------------ */ plugins { - id("java") // Tell gradle this is a java project. - id("java-library") // Import helper for source-based libraries. - id("com.diffplug.spotless") version "7.0.4" // Import auto-formatter. - id("com.gradleup.shadow") version "8.3.6" // Import shadow API. - eclipse // Import eclipse plugin for IDE integration. + id("java") // Import Java plugin. + id("java-library") // Import Java Library plugin. + id("com.diffplug.spotless") version "7.0.4" // Import Spotless plugin. + id("com.gradleup.shadow") version "8.3.6" // Import Shadow plugin. + id("checkstyle") // Import Checkstyle plugin. + eclipse // Import Eclipse plugin. + kotlin("jvm") version "2.1.21" // Import Kotlin JVM plugin. id("io.freefair.lombok") version "8.13.1" // Import automated lombok support. } @@ -25,6 +27,8 @@ java { } } +kotlin { jvmToolchain(17) } + /* ----------------------------- Metadata ------------------------------ */ group = "net.trueog.gxui-og" // Declare bundle identifier. @@ -42,21 +46,19 @@ tasks.named("processResources") { /* ---------------------------- Repos ---------------------------------- */ repositories { - mavenCentral() - gradlePluginPortal() - maven { url = uri("https://repo.purpurmc.org/snapshots") } + mavenCentral() // Import the Maven Central Maven Repository. + gradlePluginPortal() // Import the Gradle Plugin Portal Maven Repository. + maven { url = uri("https://repo.purpurmc.org/snapshots") } // Import the PurpurMC Maven Repository. maven { url = uri("file://${System.getProperty("user.home")}/.m2/repository") } } /* ---------------------- Java project deps ---------------------------- */ dependencies { - compileOnly("org.purpurmc.purpur:purpur-api:1.19.4-R0.1-SNAPSHOT") // Declare purpur API version to be packaged. + compileOnly("org.purpurmc.purpur:purpur-api:1.19.4-R0.1-SNAPSHOT") // Declare Purpur API version to be packaged. compileOnly("io.github.miniplaceholders:miniplaceholders-api:2.2.3") // Import MiniPlaceholders API. - compileOnlyApi(project(":libs:Utilities-OG")) + compileOnlyApi(project(":libs:Utilities-OG")) // Import TrueOG Network Utilities-OG Java API (from source). } -apply(from = "eclipse.gradle.kts") - /* ---------------------- Reproducible jars ---------------------------- */ tasks.withType().configureEach { // Ensure reproducible .jars isPreserveFileTimestamps = false @@ -72,31 +74,40 @@ tasks.shadowJar { tasks.jar { archiveClassifier.set("part") } // Applies to root jarfile only. -tasks.build { dependsOn(tasks.spotlessApply, tasks.shadowJar) } +tasks.build { dependsOn(tasks.spotlessApply, tasks.shadowJar) } // Build depends on spotless and shadow. /* --------------------------- Javac opts ------------------------------- */ tasks.withType().configureEach { - options.compilerArgs.add("-Xlint:deprecation") // Triggers deprecation warning messages. - options.encoding = "UTF-8" - options.isFork = true + options.compilerArgs.add("-parameters") // Enable reflection for java code. + options.isFork = true // Run javac in its own process. + options.compilerArgs.add("-Xlint:deprecation") // Trigger deprecation warning messages. + options.encoding = "UTF-8" // Use UTF-8 file encoding. } /* ----------------------------- Auto Formatting ------------------------ */ spotless { java { - removeUnusedImports() - palantirJavaFormat() + eclipse().configFile("config/formatter/eclipse-java-formatter.xml") // Eclipse java formatting. + leadingTabsToSpaces() // Convert leftover leading tabs to spaces. + removeUnusedImports() // Remove imports that aren't being called. } kotlinGradle { - ktfmt().kotlinlangStyle().configure { it.setMaxWidth(120) } - target("build.gradle.kts", "settings.gradle.kts") + ktfmt().kotlinlangStyle().configure { it.setMaxWidth(120) } // JetBrains Kotlin formatting. + target("build.gradle.kts", "settings.gradle.kts") // Gradle files to format. } } -// This can't be put in eclipse.gradle.kts because Gradle is weird. -subprojects { - apply(plugin = "java-library") - apply(plugin = "eclipse") - eclipse.project.name = "${project.name}-${rootProject.name}" - tasks.withType().configureEach { archiveBaseName.set("${project.name}-${rootProject.name}") } +checkstyle { + toolVersion = "10.18.1" // Declare checkstyle version to use. + configFile = file("config/checkstyle/checkstyle.xml") // Point checkstyle to config file. + isIgnoreFailures = true // Don't fail the build if checkstyle does not pass. + isShowViolations = true // Show the violations in any IDE with the checkstyle plugin. +} + +tasks.named("compileJava") { + dependsOn("spotlessApply") // Run spotless before compiling with the JDK. +} + +tasks.named("spotlessCheck") { + dependsOn("spotlessApply") // Run spotless before checking if spotless ran. } diff --git a/config/checkstyle/checkstyle.xml b/config/checkstyle/checkstyle.xml new file mode 100644 index 0000000..4c3ab95 --- /dev/null +++ b/config/checkstyle/checkstyle.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/config/formatter/eclipse-java-formatter.xml b/config/formatter/eclipse-java-formatter.xml new file mode 100644 index 0000000..a3e01a0 --- /dev/null +++ b/config/formatter/eclipse-java-formatter.xml @@ -0,0 +1,404 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libs/Utilities-OG b/libs/Utilities-OG index 0ba116b..4b73071 160000 --- a/libs/Utilities-OG +++ b/libs/Utilities-OG @@ -1 +1 @@ -Subproject commit 0ba116b1ababd35e804fd2c61b80be9e4aa6d57a +Subproject commit 4b730712ad072426072dbb3d4ecfcee6f7883fd5 diff --git a/src/main/java/net/trueog/gxui/GUIBase.java b/src/main/java/net/trueog/gxui/GUIBase.java index 42f5840..4aef4c3 100644 --- a/src/main/java/net/trueog/gxui/GUIBase.java +++ b/src/main/java/net/trueog/gxui/GUIBase.java @@ -68,6 +68,7 @@ public abstract class GUIBase implements Listener { private HashMap itemTimings; public GUIBase(JavaPlugin plugin, Player player, String inventoryName, int inventorySize, boolean fillEmpty) { + this.plugin = plugin; this.player = player; this.inventoryName = inventoryName; @@ -82,18 +83,13 @@ public abstract class GUIBase implements Listener { itemErrors = new HashMap<>(); itemTimings = new HashMap<>(); + } - public GUIBase( - JavaPlugin plugin, - Player player, - String inventoryName, - int inventorySize, - boolean fillEmpty, - Sound openSound, - float openSoundFloat, - Sound errorSound, - float errorSoundFloat) { + public GUIBase(JavaPlugin plugin, Player player, String inventoryName, int inventorySize, boolean fillEmpty, + Sound openSound, float openSoundFloat, Sound errorSound, float errorSoundFloat) + { + this.plugin = plugin; this.player = player; this.inventoryName = inventoryName; @@ -109,11 +105,15 @@ public abstract class GUIBase implements Listener { itemErrors = new HashMap<>(); itemTimings = new HashMap<>(); + } public void open(boolean refresh) { - if (!isOpen) Bukkit.getServer().getPluginManager().registerEvents(this, plugin); - if (openSound != null) player.playSound(player.getLocation(), openSound, 100f, openSoundFloat); + + if (!isOpen) + Bukkit.getServer().getPluginManager().registerEvents(this, plugin); + if (openSound != null) + player.playSound(player.getLocation(), openSound, 100f, openSoundFloat); isOpen = true; Inventory playersInventory = player.getInventory(); @@ -125,31 +125,42 @@ public abstract class GUIBase implements Listener { setupItems(); for (Map.Entry i : inventoryContents.entrySet()) { + inventory.setItem(i.getKey(), i.getValue().build()); + } if (fillEmpty) { + for (int i = 0; i < inventorySize; i++) { + if (inventory.getItem(i) == null) { + inventory.setItem(i, fillSlot()); + } + } + } player.openInventory(inventory); if (refresh) { + new BukkitRunnable() { @Override public void run() { - Inventory inventory = - ((HumanEntity) player).getOpenInventory().getTopInventory(); + + Inventory inventory = ((HumanEntity) player).getOpenInventory().getTopInventory(); Component inventoryTitle = player.getOpenInventory().title(); String inventoryTitleText = inventoryTitle.examinableName(); if (!inventoryTitleText.equalsIgnoreCase(inventoryName)) { + cancel(); return; + } inventory.clear(); @@ -157,14 +168,11 @@ public abstract class GUIBase implements Listener { setupItems(); int counter = 0; for (Map.Entry i : inventoryContents.entrySet()) { + if (itemErrors.containsKey(i.getKey())) { - GUIItem error = new GUIItem( - Material.RED_STAINED_GLASS_PANE, - 1, - addLinebreaks(itemErrors.get(i.getKey()), 30, "&7") - .get(counter), - "&c&lERROR"); + GUIItem error = new GUIItem(Material.RED_STAINED_GLASS_PANE, 1, + addLinebreaks(itemErrors.get(i.getKey()), 30, "&7").get(counter), "&c&lERROR"); counter++; int tick = itemTimings.get(i.getKey()); @@ -173,87 +181,112 @@ public abstract class GUIBase implements Listener { itemTimings.put(i.getKey(), tick); if (tick >= 9) { + itemErrors.remove(i.getKey()); itemTimings.remove(i.getKey()); inventory.setItem(i.getKey(), i.getValue().build()); continue; + } inventory.setItem(i.getKey(), error.build()); continue; + } inventory.setItem(i.getKey(), i.getValue().build()); + } if (fillEmpty) { + for (int i = 0; i < inventorySize; i++) { + if (inventory.getItem(i) == null) { + inventory.setItem(i, fillSlot()); + } + } + } + } + }.runTaskTimer(plugin, 0, 5); + } + } public abstract void setupItems(); public static ArrayList convertToTextComponents(List stringList) { + ArrayList textComponents = new ArrayList<>(); for (String str : stringList) { - TextComponent textComponent = - LegacyComponentSerializer.legacyAmpersand().deserialize(str); + + TextComponent textComponent = LegacyComponentSerializer.legacyAmpersand().deserialize(str); textComponents.add(textComponent); + } return textComponents; + } public void addItem(Integer slot, GUIItem item) { + inventoryContents.put(slot, item); + } private ItemStack fillSlot() { + ItemStack i = new ItemStack(Material.GRAY_STAINED_GLASS_PANE, 1); ItemMeta m = i.getItemMeta(); - TextComponent emptySlotDisplayName = - LegacyComponentSerializer.legacyAmpersand().deserialize(" "); + TextComponent emptySlotDisplayName = LegacyComponentSerializer.legacyAmpersand().deserialize(" "); m.displayName(emptySlotDisplayName); i.setItemMeta(m); return i; + } @EventHandler public void onDrop(PlayerDropItemEvent event) { + if (event.getItemDrop().getItemStack().getItemMeta().isUnbreakable()) { + event.setCancelled(true); + } + } - /*@EventHandler - public void inventoryClickHandler(InventoryClickEvent e) { - Player p = (Player) e.getWhoClicked(); - Inventory i = e.getClickedInventory(); - if(e.getCurrentItem().getItemMeta().isUnbreakable()) { - if(i.getTitle() != p.getInventory().getTitle()) { - e.setCancelled(true); - } - } - }*/ + /* + * @EventHandler public void inventoryClickHandler(InventoryClickEvent e) { + * Player p = (Player) e.getWhoClicked(); Inventory i = e.getClickedInventory(); + * if(e.getCurrentItem().getItemMeta().isUnbreakable()) { if(i.getTitle() != + * p.getInventory().getTitle()) { e.setCancelled(true); } } } + */ @EventHandler public void inventoryDragHandler(InventoryDragEvent event) { + if (event.getCursor().getItemMeta().isUnbreakable()) { + event.setCancelled(true); + } + } @EventHandler public void playerInventoryClickHandler(InventoryClickEvent event) { + Player clickedPlayer = (Player) event.getWhoClicked(); ClickType clickType = event.getClick(); Inventory inventory = event.getClickedInventory(); @@ -261,63 +294,89 @@ public abstract class GUIBase implements Listener { Component inventoryName = event.getView().title(); String inventoryTitleText = inventoryName.examinableName(); - if (clickedPlayer != player) return; + if (clickedPlayer != player) + return; - if (inventory == null) return; + if (inventory == null) + return; if (inventoryTitleText.equalsIgnoreCase(inventoryName.examinableName())) { + if (item == null || !item.hasItemMeta()) { - if (errorSound != null) player.playSound(player.getLocation(), errorSound, 50f, errorSoundFloat); + + if (errorSound != null) + player.playSound(player.getLocation(), errorSound, 50f, errorSoundFloat); event.setCancelled(true); return; + } if (itemErrors.containsKey(event.getSlot())) { + player.playSound(player.getLocation(), Sound.BLOCK_NOTE_BLOCK_BASS, 50f, 0.7f); event.setCancelled(true); return; + } if (inventoryContents.containsKey(event.getSlot())) { + GUIItem guiItem = inventoryContents.get(event.getSlot()); event.setCancelled(true); if (!guiItem.isButton()) { + if (guiItem.isPlayErrorSound() && errorSound != null) player.playSound(player.getLocation(), errorSound, 50f, errorSoundFloat); event.setCancelled(true); return; + } boolean exec = guiItem.executeClick(clickType); if (!exec) { + if (guiItem.isPlayErrorSound() && errorSound != null) player.playSound(player.getLocation(), errorSound, 100f, errorSoundFloat); + } + } + } + } @EventHandler(priority = EventPriority.HIGHEST) public void close(InventoryCloseEvent event) { + Player closer = (Player) event.getPlayer(); Component inventoryTitle = player.getOpenInventory().title(); String inventoryTitleText = inventoryTitle.examinableName(); if (inventoryTitleText.equalsIgnoreCase(inventoryName) && isOpen) { + if (closer == player) { + HandlerList.unregisterAll(this); isOpen = false; + } + } + } public void showErrorItem(Player player, Integer item, String error, boolean sound) { + itemErrors.put(item, error); itemTimings.put(item, 0); - if (sound) player.playSound(player.getLocation(), Sound.BLOCK_NOTE_BLOCK_BASS, 100f, 0.7f); + if (sound) + player.playSound(player.getLocation(), Sound.BLOCK_NOTE_BLOCK_BASS, 100f, 0.7f); + } public ArrayList addLinebreaks(String input, int maxLineLength, String toAppendAfterNewline) { + ArrayList result = new ArrayList<>(); StringTokenizer tok = new StringTokenizer(input, " "); @@ -325,19 +384,27 @@ public abstract class GUIBase implements Listener { output.insert(0, toAppendAfterNewline); int lineLen = 0; while (tok.hasMoreTokens()) { + String word = tok.nextToken(); if (lineLen + word.length() > maxLineLength) { + result.add(output.toString()); output = new StringBuilder(); output.append(toAppendAfterNewline); lineLen = 0; + } + output.append(word).append(" "); lineLen += word.length(); + } + result.add(output.toString()); return result; + } + } diff --git a/src/main/java/net/trueog/gxui/GUIButton.java b/src/main/java/net/trueog/gxui/GUIButton.java index a59999e..1162a11 100644 --- a/src/main/java/net/trueog/gxui/GUIButton.java +++ b/src/main/java/net/trueog/gxui/GUIButton.java @@ -9,4 +9,5 @@ public abstract interface GUIButton { public abstract boolean rightClick(); public abstract boolean rightClickShift(); + } diff --git a/src/main/java/net/trueog/gxui/GUIItem.java b/src/main/java/net/trueog/gxui/GUIItem.java index ce9db77..30a5381 100644 --- a/src/main/java/net/trueog/gxui/GUIItem.java +++ b/src/main/java/net/trueog/gxui/GUIItem.java @@ -64,6 +64,7 @@ public class GUIItem { lore = new ArrayList<>(); type = -1; playErrorSound = true; + } public GUIItem(Material item) { @@ -75,6 +76,7 @@ public class GUIItem { lore = new ArrayList<>(); type = -1; playErrorSound = true; + } public GUIItem(GUIButton guibutton) { @@ -84,6 +86,7 @@ public class GUIItem { lore = new ArrayList<>(); type = -1; playErrorSound = true; + } public GUIItem(Material item, int amount, String displayName) { @@ -95,6 +98,7 @@ public class GUIItem { lore = new ArrayList<>(); type = -1; playErrorSound = true; + } public GUIItem(Material item, int amount, String displayName, String skullOwner) { @@ -108,6 +112,7 @@ public class GUIItem { lore = new ArrayList<>(); type = -1; playErrorSound = true; + } public GUIItem(Material item, int amount, GUIButton button, String displayName, String skullOwner) { @@ -122,16 +127,19 @@ public class GUIItem { lore = new ArrayList<>(); type = -1; playErrorSound = true; + } public GUIButton getButton() { return button; + } public void setButton(GUIButton button) { this.button = button; + } /** @@ -154,12 +162,14 @@ public class GUIItem { } else { i = new ItemStack(item, amount); + } ItemMeta m = i.getItemMeta(); if (!displayName.equals("Not Set")) { m.displayName(displayNameTextComponent); + } m.lore(loreTextComponent); @@ -169,7 +179,9 @@ public class GUIItem { for (Map.Entry e : enchantments.entrySet()) { m.addEnchant(e.getKey(), e.getValue(), true); + } + } i.setItemMeta(m); @@ -184,11 +196,13 @@ public class GUIItem { if (!displayName.equals("Not Set")) { m.displayName(displayNameTextComponent); + } i.setUnbreakable(unbreakable); m.lore(loreTextComponent); i.setItemMeta(m); + } } catch (Exception error) { @@ -196,29 +210,35 @@ public class GUIItem { error.printStackTrace(); return new ItemStack(Material.DIRT); + } return i; + } public boolean isPlayErrorSound() { return playErrorSound; + } public void setPlayErrorSound(boolean playErrorSound) { this.playErrorSound = playErrorSound; + } public boolean isButton() { return !(button == null); + } public boolean executeClick(ClickType clickType) { switch (clickType) { + case LEFT: return button.leftClick(); case SHIFT_LEFT: @@ -229,7 +249,9 @@ public class GUIItem { return button.rightClickShift(); default: return false; + } + } public GUIItem enchantment(Enchantment ench, Integer level) { @@ -237,15 +259,19 @@ public class GUIItem { if (enchantments == null) { enchantments = new HashMap<>(); + } enchantments.put(ench, level); return this; + } public GUIItem duplicateByConstructor() { return new GUIItem(item, amount, displayName); + } + }