From 2c7da9dd4e71dd0a6d795243145f990198467d7a Mon Sep 17 00:00:00 2001 From: Wolfieheart Date: Sun, 28 Apr 2024 19:11:29 +0200 Subject: [PATCH 01/40] [Rewrite] Remove and start fresh, Paper Only and going from there :D Signed-off-by: Wolfieheart --- API-Example-Plugin/pom.xml | 115 --- .../rypofalem/apiexample/ASEventTester.java | 94 -- .../apiexample/ArmorStandEditorAPITest.java | 33 - .../rypofalem/apiexample/IFEventTester.java | 77 -- .../src/main/resources/plugin.yml | 7 - .../ArmorStandEditorPlugin.java | 681 -------------- .../rypofalem/armorstandeditor/CommandEx.java | 628 ------------- .../rypofalem/armorstandeditor/Metrics.java | 881 ------------------ .../armorstandeditor/PlayerEditor.java | 684 -------------- .../armorstandeditor/PlayerEditorManager.java | 493 ---------- .../rypofalem/armorstandeditor/Scheduler.java | 108 --- .../rypofalem/armorstandeditor/Util.java | 69 -- .../armorstandeditor/api/ArmorStandEvent.java | 36 - .../api/ArmorStandManipulatedEvent.java | 54 -- .../api/ArmorStandRenameEvent.java | 59 -- .../api/ArmorStandTargetedEvent.java | 54 -- .../armorstandeditor/api/ItemFrameEvent.java | 36 - .../api/ItemFrameGlowEvent.java | 35 - .../api/ItemFrameManipulatedEvent.java | 55 -- .../api/ItemFrameTargetedEvent.java | 54 -- .../api/PlayerOpenMenuEvent.java | 52 -- .../armorstandeditor/language/Language.java | 136 --- .../armorstandeditor/menu/ASEHolder.java | 33 - .../armorstandeditor/menu/EquipmentMenu.java | 118 --- .../armorstandeditor/menu/ItemFactory.java | 130 --- .../rypofalem/armorstandeditor/menu/Menu.java | 294 ------ .../menu/PresetArmorPosesMenu.java | 264 ------ .../modes/AdjustmentMode.java | 34 - .../modes/ArmorStandData.java | 52 -- .../armorstandeditor/modes/Axis.java | 34 - .../armorstandeditor/modes/CopySlots.java | 46 - .../armorstandeditor/modes/EditMode.java | 38 - .../protections/BentoBoxProtection.java | 95 -- .../protections/GriefDefenderProtection.java | 59 -- .../GriefPreventionProtection.java | 73 -- .../protections/LandsProtection.java | 93 -- .../protections/PlotSquaredProtection.java | 80 -- .../protections/Protection.java | 26 - .../protections/SkyblockProtection.java | 55 -- .../protections/TownyProtection.java | 50 - .../protections/WorldGuardProtection.java | 55 -- .../armorstandeditor/utils/Configuration.java | 78 -- src/main/resources/config.yml | 107 --- src/main/resources/lang/de_DE.yml | 356 ------- src/main/resources/lang/en_US.yml | 372 -------- src/main/resources/lang/es_ES.yml | 347 ------- src/main/resources/lang/fr_FR.yml | 353 ------- src/main/resources/lang/ja_JP.yml | 353 ------- src/main/resources/lang/nl_NL.yml | 353 ------- src/main/resources/lang/pl_PL.yml | 332 ------- src/main/resources/lang/pt_BR.yml | 355 ------- src/main/resources/lang/ro_RO.yml | 324 ------- src/main/resources/lang/ru_RU.yml | 321 ------- src/main/resources/lang/test_NA.yml | 376 -------- src/main/resources/lang/uk_UA.yml | 317 ------- src/main/resources/lang/zh_CN.yml | 356 ------- 56 files changed, 10770 deletions(-) delete mode 100644 API-Example-Plugin/pom.xml delete mode 100644 API-Example-Plugin/src/main/java/io/github/rypofalem/apiexample/ASEventTester.java delete mode 100644 API-Example-Plugin/src/main/java/io/github/rypofalem/apiexample/ArmorStandEditorAPITest.java delete mode 100644 API-Example-Plugin/src/main/java/io/github/rypofalem/apiexample/IFEventTester.java delete mode 100644 API-Example-Plugin/src/main/resources/plugin.yml delete mode 100644 src/main/java/io/github/rypofalem/armorstandeditor/CommandEx.java delete mode 100644 src/main/java/io/github/rypofalem/armorstandeditor/Metrics.java delete mode 100644 src/main/java/io/github/rypofalem/armorstandeditor/PlayerEditor.java delete mode 100644 src/main/java/io/github/rypofalem/armorstandeditor/PlayerEditorManager.java delete mode 100644 src/main/java/io/github/rypofalem/armorstandeditor/Scheduler.java delete mode 100644 src/main/java/io/github/rypofalem/armorstandeditor/Util.java delete mode 100644 src/main/java/io/github/rypofalem/armorstandeditor/api/ArmorStandEvent.java delete mode 100644 src/main/java/io/github/rypofalem/armorstandeditor/api/ArmorStandManipulatedEvent.java delete mode 100644 src/main/java/io/github/rypofalem/armorstandeditor/api/ArmorStandRenameEvent.java delete mode 100644 src/main/java/io/github/rypofalem/armorstandeditor/api/ArmorStandTargetedEvent.java delete mode 100644 src/main/java/io/github/rypofalem/armorstandeditor/api/ItemFrameEvent.java delete mode 100644 src/main/java/io/github/rypofalem/armorstandeditor/api/ItemFrameGlowEvent.java delete mode 100644 src/main/java/io/github/rypofalem/armorstandeditor/api/ItemFrameManipulatedEvent.java delete mode 100644 src/main/java/io/github/rypofalem/armorstandeditor/api/ItemFrameTargetedEvent.java delete mode 100644 src/main/java/io/github/rypofalem/armorstandeditor/api/PlayerOpenMenuEvent.java delete mode 100644 src/main/java/io/github/rypofalem/armorstandeditor/language/Language.java delete mode 100644 src/main/java/io/github/rypofalem/armorstandeditor/menu/ASEHolder.java delete mode 100644 src/main/java/io/github/rypofalem/armorstandeditor/menu/EquipmentMenu.java delete mode 100644 src/main/java/io/github/rypofalem/armorstandeditor/menu/ItemFactory.java delete mode 100644 src/main/java/io/github/rypofalem/armorstandeditor/menu/Menu.java delete mode 100644 src/main/java/io/github/rypofalem/armorstandeditor/menu/PresetArmorPosesMenu.java delete mode 100644 src/main/java/io/github/rypofalem/armorstandeditor/modes/AdjustmentMode.java delete mode 100644 src/main/java/io/github/rypofalem/armorstandeditor/modes/ArmorStandData.java delete mode 100644 src/main/java/io/github/rypofalem/armorstandeditor/modes/Axis.java delete mode 100644 src/main/java/io/github/rypofalem/armorstandeditor/modes/CopySlots.java delete mode 100644 src/main/java/io/github/rypofalem/armorstandeditor/modes/EditMode.java delete mode 100644 src/main/java/io/github/rypofalem/armorstandeditor/protections/BentoBoxProtection.java delete mode 100644 src/main/java/io/github/rypofalem/armorstandeditor/protections/GriefDefenderProtection.java delete mode 100644 src/main/java/io/github/rypofalem/armorstandeditor/protections/GriefPreventionProtection.java delete mode 100644 src/main/java/io/github/rypofalem/armorstandeditor/protections/LandsProtection.java delete mode 100644 src/main/java/io/github/rypofalem/armorstandeditor/protections/PlotSquaredProtection.java delete mode 100644 src/main/java/io/github/rypofalem/armorstandeditor/protections/Protection.java delete mode 100644 src/main/java/io/github/rypofalem/armorstandeditor/protections/SkyblockProtection.java delete mode 100644 src/main/java/io/github/rypofalem/armorstandeditor/protections/TownyProtection.java delete mode 100644 src/main/java/io/github/rypofalem/armorstandeditor/protections/WorldGuardProtection.java delete mode 100644 src/main/java/io/github/rypofalem/armorstandeditor/utils/Configuration.java delete mode 100644 src/main/resources/config.yml delete mode 100644 src/main/resources/lang/de_DE.yml delete mode 100644 src/main/resources/lang/en_US.yml delete mode 100644 src/main/resources/lang/es_ES.yml delete mode 100644 src/main/resources/lang/fr_FR.yml delete mode 100644 src/main/resources/lang/ja_JP.yml delete mode 100644 src/main/resources/lang/nl_NL.yml delete mode 100644 src/main/resources/lang/pl_PL.yml delete mode 100644 src/main/resources/lang/pt_BR.yml delete mode 100644 src/main/resources/lang/ro_RO.yml delete mode 100644 src/main/resources/lang/ru_RU.yml delete mode 100644 src/main/resources/lang/test_NA.yml delete mode 100644 src/main/resources/lang/uk_UA.yml delete mode 100644 src/main/resources/lang/zh_CN.yml diff --git a/API-Example-Plugin/pom.xml b/API-Example-Plugin/pom.xml deleted file mode 100644 index 4e90681c..00000000 --- a/API-Example-Plugin/pom.xml +++ /dev/null @@ -1,115 +0,0 @@ - - 4.0.0 - io.github.rypofalem.apiexample - armorstandeditor-apitest - jar - 1.20.1-43.2 - armorstandeditor-apitest - s://maven.apache.org - - - 17 - UTF-8 - 3.0.1 - wolfieheart - https://sonarcloud.io - - - - - Wolfieheart - Wolfieheart - https://github.com/Wolfieheart - - - RypoFalem - RypoFalem - https://github.com/RypoFalem - - - - - - - spigot-repo - https://hub.spigotmc.org/nexus/content/repositories/snapshots/ - - - paper-repo - https://repo.papermc.io/repository/maven-public/ - - - jitpack.io - https://jitpack.io - - - - - - - org.spigotmc - spigot-api - 1.20.1-R0.1-SNAPSHOT - provided - - - dev.folia - folia-api - 1.19.4-R0.1-SNAPSHOT - provided - - - com.github.wolfieheart - armorstandeditor - 1.20.2-44.1 - provided - - - - - - - org.codehaus.mojo - build-helper-maven-plugin - 3.5.0 - - - compile - package - - attach-artifact - - - - - ${project.build.directory}/${project.artifactId}.jar - jar - optional - - - - - - - - org.apache.maven.plugins - maven-compiler-plugin - 3.12.0 - - 17 - 17 - - - - org.apache.maven.plugins - maven-release-plugin - ${maven-release-plugin.version} - - [ci skip] || [CI SKIP] || [CI-SKIP] - @{project.version} - - - - - diff --git a/API-Example-Plugin/src/main/java/io/github/rypofalem/apiexample/ASEventTester.java b/API-Example-Plugin/src/main/java/io/github/rypofalem/apiexample/ASEventTester.java deleted file mode 100644 index 06e6d50b..00000000 --- a/API-Example-Plugin/src/main/java/io/github/rypofalem/apiexample/ASEventTester.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * ArmorStandEditor: Bukkit plugin to allow editing armor stand attributes - * Copyright (C) 2016-2023 RypoFalem - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -package io.github.rypofalem.apiexample; - -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.player.PlayerInteractAtEntityEvent; -import org.bukkit.event.player.PlayerInteractEvent; -import org.bukkit.event.player.PlayerSwapHandItemsEvent; - -public class ASEventTester implements Listener { - - Player player; - - //ArmorStandRenameEvent - @EventHandler - public void renameArmorStand(PlayerInteractAtEntityEvent ASRenameEvent) { - player = ASRenameEvent.getPlayer(); - ASRenameEvent.setCancelled(true); - if (ASRenameEvent.isCancelled()) { - player.sendMessage("ArmorStandRenameEvent has been cancelled"); - } else { - player.sendMessage("ArmorStandRenameEvent has not been cancelled. Continuing...."); - } - } - - //ArmorStandManipEvent - @EventHandler - public void manipulateArmorStand(PlayerInteractAtEntityEvent ASManipEvent) { - player = ASManipEvent.getPlayer(); - ASManipEvent.setCancelled(true); - if (ASManipEvent.isCancelled()) { - player.sendMessage("ArmorStandManipulationEvent has been cancelled"); - } else { - player.sendMessage("ArmorStandManipulationEvent has not been cancelled. Continuing...."); - } - } - - //ArmorStandTargetedEvent - @EventHandler - public void targetEvent(PlayerSwapHandItemsEvent targetASEvent) { - player = targetASEvent.getPlayer(); - targetASEvent.setCancelled(true); - if (targetASEvent.isCancelled()) { - player.sendMessage("ArmorStandTargetedEvent has been cancelled"); - } else { - player.sendMessage("ArmorStandTargetedEvent has not been cancelled. Continuing...."); - } - } - - //PlayerOpenMenuEvent - //onArmorStandDamage EntityDamageByEntityEvent event - @EventHandler - public void playerOpeningMenuEvent(EntityDamageByEntityEvent ASEDamageMenuOpenEvent) { - player = (Player) ASEDamageMenuOpenEvent.getDamager(); - ASEDamageMenuOpenEvent.setCancelled(true); - if (ASEDamageMenuOpenEvent.isCancelled()) { - player.sendMessage("PlayerOpenMenuEvent has been cancelled"); - } else { - player.sendMessage("PlayerOpenMenuEvent has not been cancelled. Continuing...."); - } - } - - //Also PlayerOpenMenuEvent when RightClicking/Interacting - @EventHandler - public void playerOpeningMenuRightClickEvent(PlayerInteractEvent ASERightClickMenuOpenEvent) { - player = ASERightClickMenuOpenEvent.getPlayer(); - ASERightClickMenuOpenEvent.setCancelled(true); - if (ASERightClickMenuOpenEvent.isCancelled()) { - player.sendMessage("PlayerOpenMenuEvent has been cancelled"); - } else { - player.sendMessage("PlayerOpenMenuEvent has not been cancelled. Continuing...."); - } - } -} diff --git a/API-Example-Plugin/src/main/java/io/github/rypofalem/apiexample/ArmorStandEditorAPITest.java b/API-Example-Plugin/src/main/java/io/github/rypofalem/apiexample/ArmorStandEditorAPITest.java deleted file mode 100644 index 7d366781..00000000 --- a/API-Example-Plugin/src/main/java/io/github/rypofalem/apiexample/ArmorStandEditorAPITest.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * ArmorStandEditor: Bukkit plugin to allow editing armor stand attributes - * Copyright (C) 2016-2023 RypoFalem - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -package io.github.rypofalem.apiexample; - -import org.bukkit.plugin.java.JavaPlugin; - -public class ArmorStandEditorAPITest extends JavaPlugin { - - @Override - public void onEnable() { - this.getLogger().info("[ArmorStandEditor] API Testing Plugin v1.20.0-43 - Enable"); - this.getServer().getPluginManager().registerEvents(new ASEventTester(), this); - this.getServer().getPluginManager().registerEvents(new IFEventTester(), this); - } - -} diff --git a/API-Example-Plugin/src/main/java/io/github/rypofalem/apiexample/IFEventTester.java b/API-Example-Plugin/src/main/java/io/github/rypofalem/apiexample/IFEventTester.java deleted file mode 100644 index d80bf182..00000000 --- a/API-Example-Plugin/src/main/java/io/github/rypofalem/apiexample/IFEventTester.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * ArmorStandEditor: Bukkit plugin to allow editing armor stand attributes - * Copyright (C) 2016-2023 RypoFalem - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -package io.github.rypofalem.apiexample; - -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.player.PlayerInteractAtEntityEvent; -import org.bukkit.event.player.PlayerSwapHandItemsEvent; - -public class IFEventTester implements Listener { - Player player; - - //ItemFrameGlowEvent - @EventHandler - public void manipulateArmorStand(PlayerInteractAtEntityEvent IFGlowEvent) { - player = IFGlowEvent.getPlayer(); - IFGlowEvent.setCancelled(true); - if (IFGlowEvent.isCancelled()) { - player.sendMessage("ItemFrameGlowEvent has been cancelled"); - } else { - player.sendMessage("ItemFrameGlowEvent has not been cancelled. Continuing...."); - } - } - - @EventHandler - public void manipulateItemFrame(EntityDamageByEntityEvent IFManipulationLeftClickEvent) { - player = (Player) IFManipulationLeftClickEvent.getDamager(); - IFManipulationLeftClickEvent.setCancelled(true); - if (IFManipulationLeftClickEvent.isCancelled()) { - player.sendMessage("ItemFrameManipulatedEvent has been cancelled"); - } else { - player.sendMessage("ItemFrameManipulatedEvent has not been cancelled. Continuing...."); - } - } - - @EventHandler - public void manipulateItemFrameRightClick(PlayerInteractAtEntityEvent IFManipulationRightClickEvent) { - player = IFManipulationRightClickEvent.getPlayer(); - IFManipulationRightClickEvent.setCancelled(true); - if (IFManipulationRightClickEvent.isCancelled()) { - player.sendMessage("ItemFrameManipulatedEvent has been cancelled"); - } else { - player.sendMessage("ItemFrameManipulatedEvent has not been cancelled. Continuing...."); - } - } - - @EventHandler - public void targetEvent(PlayerSwapHandItemsEvent targetIFEvent) { - player = targetIFEvent.getPlayer(); - targetIFEvent.setCancelled(true); - if (targetIFEvent.isCancelled()) { - player.sendMessage("ItemFrameTargetedEvent has been cancelled"); - } else { - player.sendMessage("ItemFrameTargetedEvent has not been cancelled. Continuing...."); - } - } - -} diff --git a/API-Example-Plugin/src/main/resources/plugin.yml b/API-Example-Plugin/src/main/resources/plugin.yml deleted file mode 100644 index 407101c7..00000000 --- a/API-Example-Plugin/src/main/resources/plugin.yml +++ /dev/null @@ -1,7 +0,0 @@ -name: ArmorStandEditor-APITester -main: io.github.rypofalem.apiexample.ArmorStandEditorAPITest -version: 1.20.1-43.2 -api-version: "1.13" -website: https://www.spigotmc.org/resources/94503/ -authors: [Wolfstorm, Pinnkk] -description: Allows players to edit data of armorstands without any commands. diff --git a/src/main/java/io/github/rypofalem/armorstandeditor/ArmorStandEditorPlugin.java b/src/main/java/io/github/rypofalem/armorstandeditor/ArmorStandEditorPlugin.java index b6a8d3bd..16fee9c3 100644 --- a/src/main/java/io/github/rypofalem/armorstandeditor/ArmorStandEditorPlugin.java +++ b/src/main/java/io/github/rypofalem/armorstandeditor/ArmorStandEditorPlugin.java @@ -19,700 +19,19 @@ package io.github.rypofalem.armorstandeditor; -import com.jeff_media.updatechecker.UpdateCheckSource; -import com.jeff_media.updatechecker.UpdateChecker; -import com.jeff_media.updatechecker.UserAgentBuilder; - -import io.github.rypofalem.armorstandeditor.Metrics.*; -import io.github.rypofalem.armorstandeditor.language.Language; - -import org.bukkit.*; -import org.bukkit.entity.Player; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.Damageable; -import org.bukkit.inventory.meta.ItemMeta; -import org.bukkit.plugin.PluginDescriptionFile; import org.bukkit.plugin.java.JavaPlugin; -import org.bukkit.scoreboard.Scoreboard; -import org.bukkit.scoreboard.Team; - -import java.io.File; -import java.util.*; -import java.util.logging.Level; public class ArmorStandEditorPlugin extends JavaPlugin { - //!!! DO NOT REMOVE THESE UNDER ANY CIRCUMSTANCES - Required for BStats and UpdateChecker !!! - public static final int SPIGOT_RESOURCE_ID = 94503; //Used for Update Checker - private static final int PLUGIN_ID = 12668; //Used for BStats Metrics - - private NamespacedKey iconKey; - private static ArmorStandEditorPlugin instance; - private Language lang; - - //Server Version Detection: Paper or Spigot and Invalid NMS Version - String nmsVersion; - String languageFolderLocation = "lang/"; - String warningMCVer = "Minecraft Version: "; - public boolean hasSpigot = false; - public boolean hasPaper = false; - public boolean hasFolia = false; - String nmsVersionNotLatest = null; - PluginDescriptionFile pdfFile = this.getDescription(); - public static final String SEPARATOR_FIELD = "================================"; - - public PlayerEditorManager editorManager; - - //Output for Updates - boolean opUpdateNotification = false; - boolean runTheUpdateChecker = false; - double updateCheckerInterval; - - //Edit Tool Information - Material editTool; - String toolType; - int editToolData = Integer.MIN_VALUE; - boolean requireToolData = false; - boolean requireToolName = false; - String editToolName = null; - boolean requireToolLore = false; - List editToolLore = null; - boolean enablePerWorld = false; - List allowedWorldList = null; - boolean allowCustomModelData = false; - Integer customModelDataInt = Integer.MIN_VALUE; - - //GUI Settings - boolean requireSneaking = false; - boolean sendToActionBar = true; - - //Armor Stand Specific Settings - double coarseRot; - double fineRot; - boolean glowItemFrames = false; - boolean invisibleItemFrames = true; - boolean armorStandVisibility = true; - - //Misc Options - boolean allowedToRetrievePlayerHead = false; - boolean adminOnlyNotifications = false; - - //Glow Entity Colors - public Scoreboard scoreboard; - public Team team; - String lockedTeam = "ASLocked"; - - //Debugging Options.... Not Exposed - boolean debugFlag; - - private static ArmorStandEditorPlugin plugin; - - public ArmorStandEditorPlugin() { - instance = this; - } - @Override public void onEnable() { - if (!Scheduler.isFolia()) - scoreboard = Objects.requireNonNull(this.getServer().getScoreboardManager()).getMainScoreboard(); - - //Get NMS Version - nmsVersion = getNmsVersion(); - - //Load Messages in Console - getLogger().info("======= ArmorStandEditor ======="); - getLogger().info("Plugin Version: " + pdfFile.getVersion()); - - // Check if the Minecraft version is supported - if (nmsVersion.compareTo("v1_17") < 0) { - getLogger().log(Level.WARNING, warningMCVer + "{0}", nmsVersion); - getLogger().warning("ArmorStandEditor is not compatible with this version of Minecraft. Please update to at least version 1.17. Loading failed."); - getServer().getPluginManager().disablePlugin(this); - getLogger().info(SEPARATOR_FIELD); - return; - } - - //Also Warn People to Update if using nmsVersion lower than latest - if (nmsVersion.compareTo("v1_20") < 0) { - getLogger().log(Level.WARNING, warningMCVer + "{0}", nmsVersion); - getLogger().warning("ArmorStandEditor is compatible with this version of Minecraft, but it is not the latest supported version."); - getLogger().warning("Loading continuing, but please consider updating to the latest version."); - } else { - getLogger().log(Level.INFO, warningMCVer + "{0}", nmsVersion); - getLogger().info("ArmorStandEditor is compatible with this version of Minecraft. Loading continuing."); - } - //Spigot Check - hasSpigot = getHasSpigot(); - hasPaper = getHasPaper(); - hasFolia = Scheduler.isFolia(); - - //If Paper and Spigot are both FALSE - Disable the plugin - if (!hasPaper && !hasSpigot) { - getLogger().severe("This plugin requires either Paper, Spigot or one of its forks to run. This is not an error, please do not report this!"); - getServer().getPluginManager().disablePlugin(this); - getLogger().info(SEPARATOR_FIELD); - return; - } else { - if (hasSpigot) { - getLogger().log(Level.INFO, "SpigotMC: {0}", hasSpigot); - } else { - getLogger().log(Level.INFO, "PaperMC: {0}", hasPaper); - } - } - - getServer().getPluginManager().enablePlugin(this); - - if (!hasFolia) { - scoreboard = Objects.requireNonNull(this.getServer().getScoreboardManager()).getMainScoreboard(); - registerScoreboards(scoreboard); - } else { - getServer().getLogger().warning("Scoreboards currently do not work on Folia. Scoreboard Coloring will not work"); - } - - - getLogger().info(SEPARATOR_FIELD); - - //saveResource doesn't accept File.separator on Windows, need to hardcode unix separator "/" instead - updateConfig("", "config.yml"); - updateConfig(languageFolderLocation, "de_DE.yml"); - updateConfig(languageFolderLocation, "es_ES.yml"); - updateConfig(languageFolderLocation, "fr_FR.yml"); - updateConfig(languageFolderLocation, "ja_JP.yml"); - updateConfig(languageFolderLocation, "nl_NL.yml"); - updateConfig(languageFolderLocation, "pl_PL.yml"); - updateConfig(languageFolderLocation, "pt_BR.yml"); - updateConfig(languageFolderLocation, "ro_RO.yml"); - updateConfig(languageFolderLocation, "ru_RU.yml"); - updateConfig(languageFolderLocation, "test_NA.yml"); - updateConfig(languageFolderLocation, "uk_UA.yml"); - updateConfig(languageFolderLocation, "zh_CN.yml"); - - //English is the default language and needs to be unaltered to so that there is always a backup message string - saveResource("lang/en_US.yml", true); - lang = new Language(getConfig().getString("lang"), this); - - //Rotation - coarseRot = getConfig().getDouble("coarse"); - fineRot = getConfig().getDouble("fine"); - - //Set Tool to be used in game - toolType = getConfig().getString("tool"); - if (toolType != null) { - editTool = Material.getMaterial(toolType); //Ignore Warning - } else { - getLogger().severe("Unable to get Tool for Use with Plugin. Unable to continue!"); - getLogger().info(SEPARATOR_FIELD); - getServer().getPluginManager().disablePlugin(this); - return; - } - - //Do we require a custom tool name? - requireToolName = getConfig().getBoolean("requireToolName", false); - if (requireToolName) { - editToolName = getConfig().getString("toolName", null); - if (editToolName != null) editToolName = ChatColor.translateAlternateColorCodes('&', editToolName); - } - - //Custom Model Data - allowCustomModelData = getConfig().getBoolean("allowCustomModelData", false); - - if (allowCustomModelData) { - customModelDataInt = getConfig().getInt("customModelDataInt", Integer.MIN_VALUE); - } - - //ArmorStandVisibility Node - armorStandVisibility = getConfig().getBoolean("armorStandVisibility", true); - - //Is there NBT Required for the tool - requireToolData = getConfig().getBoolean("requireToolData", false); - - if (requireToolData) { - editToolData = getConfig().getInt("toolData", Integer.MIN_VALUE); - } - - requireToolLore = getConfig().getBoolean("requireToolLore", false); - - if (requireToolLore) { - editToolLore = getConfig().getList("toolLore", null); - } - - enablePerWorld = getConfig().getBoolean("enablePerWorldSupport", false); - if(enablePerWorld) { - allowedWorldList = getConfig().getList("allowed-worlds", null); - if (allowedWorldList != null && allowedWorldList.get(0).equals("*")) { - allowedWorldList = getServer().getWorlds().stream().map(World::getName).toList(); - } - } - - //Require Sneaking - Wolfst0rm/ArmorStandEditor#17 - requireSneaking = getConfig().getBoolean("requireSneaking", false); - - //Send Messages to Action Bar - sendToActionBar = getConfig().getBoolean("sendMessagesToActionBar", true); - - //All ItemFrame Stuff - glowItemFrames = getConfig().getBoolean("glowingItemFrame", true); - invisibleItemFrames = getConfig().getBoolean("invisibleItemFrames", true); - - //Add ability to enable ot Disable the running of the Updater - runTheUpdateChecker = getConfig().getBoolean("runTheUpdateChecker", true); - - //Add Ability to check for UpdatePerms that Notify Ops - https://github.com/Wolfieheart/ArmorStandEditor/issues/86 - opUpdateNotification = getConfig().getBoolean("opUpdateNotification", true); - updateCheckerInterval = getConfig().getDouble("updateCheckerInterval", 24); - - //Ability to get Player Heads via a command - allowedToRetrievePlayerHead = getConfig().getBoolean("allowedToRetrievePlayerHead", true); - - adminOnlyNotifications = getConfig().getBoolean("adminOnlyNotifications", true); - - debugFlag = getConfig().getBoolean("debugFlag", false); - if(debugFlag){ - getServer().getLogger().warning(ArmorStandEditorPlugin.SEPARATOR_FIELD); - getServer().getLogger().warning(" ArmorStandEditor - Debug Mode "); - getServer().getLogger().warning(" Debug Mode: ENABLED! "); - getServer().getLogger().warning(" USE THIS FOR DEVELOPMENT PURPOSES ONLY! "); - getServer().getLogger().warning(ArmorStandEditorPlugin.SEPARATOR_FIELD); - } - - //Run UpdateChecker - Reports out to Console on Startup ONLY! - if (!hasFolia && runTheUpdateChecker) { - - if (opUpdateNotification) { - runUpdateCheckerWithOPNotifyOnJoinEnabled(); - } else { - runUpdateCheckerConsoleUpdateCheck(); - } - - } - - //Get Metrics from bStats - getMetrics(); - - editorManager = new PlayerEditorManager(this); - CommandEx execute = new CommandEx(this); - - //CommandExecution and TabCompletion - Objects.requireNonNull(getCommand("ase")).setExecutor(execute); - Objects.requireNonNull(getCommand("ase")).setTabCompleter(execute); - - getServer().getPluginManager().registerEvents(editorManager, this); - - } - - private void runUpdateCheckerConsoleUpdateCheck() { - if (getArmorStandEditorVersion().contains(".x")) { - getLogger().warning("Note from the development team: "); - getLogger().warning("It appears that you are using the development version of ArmorStandEditor"); - getLogger().warning("This version can be unstable and is not recommended for Production Environments."); - getLogger().warning("Please, report bugs to: https://github.com/Wolfieheart/ArmorStandEditor. "); - getLogger().warning("This warning is intended to be displayed when using a Dev build and is NOT A BUG!"); - getLogger().info("Update Checker does not work on Development Builds."); - } else { - new UpdateChecker(this, UpdateCheckSource.SPIGET, "" + SPIGOT_RESOURCE_ID + "") - .setDownloadLink("https://www.spigotmc.org/resources/armorstandeditor-reborn.94503/") - .setChangelogLink("https://www.spigotmc.org/resources/armorstandeditor-reborn.94503/history") - .setColoredConsoleOutput(true) - .setUserAgent(new UserAgentBuilder().addPluginNameAndVersion().addServerVersion()) - .checkEveryXHours(updateCheckerInterval) - .checkNow(); - } - } - - private void runUpdateCheckerWithOPNotifyOnJoinEnabled() { - if (getArmorStandEditorVersion().contains(".x")) { - getLogger().warning("Note from the development team: "); - getLogger().warning("It appears that you are using the development version of ArmorStandEditor"); - getLogger().warning("This version can be unstable and is not recommended for Production Environments."); - getLogger().warning("Please, report bugs to: https://github.com/Wolfieheart/ArmorStandEditor . "); - getLogger().warning("This warning is intended to be displayed when using a Dev build and is NOT A BUG!"); - getLogger().info("Update Checker does not work on Development Builds."); - } else { - new UpdateChecker(this, UpdateCheckSource.SPIGET, "" + SPIGOT_RESOURCE_ID + "") - .setDownloadLink("https://www.spigotmc.org/resources/armorstandeditor-reborn.94503/") - .setChangelogLink("https://www.spigotmc.org/resources/armorstandeditor-reborn.94503/history") - .setColoredConsoleOutput(true) - .setNotifyOpsOnJoin(true) - .setUserAgent(new UserAgentBuilder().addPluginNameAndVersion().addServerVersion()) - .checkEveryXHours(updateCheckerInterval) - .checkNow(); - } - } - - //Implement Glow Effects for Wolfstorm/ArmorStandEditor-Issues#5 - Add Disable Slots with Different Glow than Default - private void registerScoreboards(Scoreboard scoreboard) { - getServer().getLogger().info("Registering Scoreboards required for Glowing Effects"); - - //Fix for Scoreboard Issue reported by Starnos - Wolfst0rm/ArmorStandEditor-Issues/issues/18 - if (scoreboard.getTeam(lockedTeam) == null) { - scoreboard.registerNewTeam(lockedTeam); - scoreboard.getTeam(lockedTeam).setColor(ChatColor.RED); - } else { - getServer().getLogger().info("Scoreboard for ASLocked Already exists. Continuing to load"); - } } - private void unregisterScoreboards(Scoreboard scoreboard) { - getLogger().info("Removing Scoreboards required for Glowing Effects"); - - team = scoreboard.getTeam(lockedTeam); - if (team != null) { //Basic Sanity Check to ensure that the team is there - team.unregister(); - } else { - getLogger().severe("Team Already Appears to be removed. Please do not do this manually!"); - } - } - - private void updateConfig(String folder, String config) { - if (!new File(getDataFolder() + File.separator + folder + config).exists()) { - saveResource(folder + config, false); - } - } @Override public void onDisable() { - for (Player player : Bukkit.getServer().getOnlinePlayers()) { - if (player.getOpenInventory().getTopInventory().getHolder() == editorManager.getMenuHolder()) player.closeInventory(); - } - - if (!hasFolia) { - scoreboard = Objects.requireNonNull(this.getServer().getScoreboardManager()).getMainScoreboard(); - unregisterScoreboards(scoreboard); - } - } - - public String getNmsVersion() { - return this.getServer().getClass().getPackage().getName().replace(".", ",").split(",")[3]; - } - - public boolean getHasSpigot() { - try { - Class.forName("org.spigotmc.SpigotConfig"); - nmsVersionNotLatest = "SpigotMC ASAP."; - return true; - } catch (ClassNotFoundException e) { - nmsVersionNotLatest = ""; - return false; - } - } - - public boolean getHasPaper() { - try { - Class.forName("com.destroystokyo.paper.PaperConfig"); - nmsVersionNotLatest = "PaperMC ASAP."; - return true; - } catch (ClassNotFoundException e) { - nmsVersionNotLatest = ""; - return false; - } - } - - public boolean getHasFolia() { - return Scheduler.isFolia(); - } - public String getArmorStandEditorVersion() { - return getConfig().getString("version"); } - public boolean getArmorStandVisibility() { - return getConfig().getBoolean("armorStandVisibility"); - } - - public boolean getItemFrameVisibility() { - return getConfig().getBoolean("invisibleItemFrames"); - } - - public Language getLang() { - return lang; - } - - public boolean getAllowCustomModelData() { - return this.getConfig().getBoolean("allowCustomModelData"); - } - - public Material getEditTool() { - return this.editTool; - } - - public boolean getRunTheUpdateChecker() { - return this.getConfig().getBoolean("runTheUpdateChecker"); - } - - public Integer getCustomModelDataInt() { - return this.getConfig().getInt("customModelDataInt"); - } - - //New in 1.20-43: Allow the ability to get a player head from a command - ENABLED VIA CONFIG ONLY! - public boolean getAllowedToRetrievePlayerHead() { - return this.getConfig().getBoolean("allowedToRetrievePlayerHead"); - } - - public boolean getAdminOnlyNotifications() { - return this.getConfig().getBoolean("adminOnlyNotifications"); - } - - public boolean isEditTool(ItemStack itemStk) { - if (itemStk == null) { - return false; - } - if (editTool != itemStk.getType()) { - return false; - } - - ItemMeta itemMeta = itemStk.getItemMeta(); - if (itemMeta == null) return false; - - //FIX: Depreciated Stack for getDurability - if (requireToolData) { - Damageable d1 = (Damageable) itemMeta; //Get the Damageable Options for itemStk - if (d1 != null) { //We do this to prevent NullPointers - if (d1.getDamage() != (short) editToolData) { - return false; - } - } - } - - if (requireToolName && editToolName != null) { - if (!itemStk.hasItemMeta()) { - return false; - } - - //Get the name of the Edit Tool - If Null, return false - String itemName = itemMeta.getDisplayName(); - - //If the name of the Edit Tool is not the Name specified in Config then Return false - if (!itemName.equals(editToolName)) { - return false; - } - - } - - if (requireToolLore && editToolLore != null) { - - //If the ItemStack does not have Metadata then we return false - if (!itemStk.hasItemMeta()) { - return false; - } - - //Get the lore of the Item and if it is null - Return False - List itemLore = itemMeta.getLore(); - - //If the Item does not have Lore - Return False - boolean hasTheItemLore = itemMeta.hasLore(); - if (!hasTheItemLore) { - return false; - } - - //Get the localised ListString of editToolLore - List listStringOfEditToolLore = (List) editToolLore; - - //Return False if itemLore on the item does not match what we expect in the config. - if (!itemLore.equals(listStringOfEditToolLore)) { - return false; - } - - } - - if (allowCustomModelData && customModelDataInt != null) { - //If the ItemStack does not have Metadata then we return false - if (!itemStk.hasItemMeta()) { - return false; - } - Integer itemCustomModel = itemMeta.getCustomModelData(); - return itemCustomModel.equals(customModelDataInt); - } - return true; - } - public void performReload() { - - //Unregister Scoreboard before before performing the reload - if (!hasFolia) { - scoreboard = Objects.requireNonNull(this.getServer().getScoreboardManager()).getMainScoreboard(); - unregisterScoreboards(scoreboard); - } - - //Perform Reload - reloadConfig(); - - //Re-Register Scoreboards - if (!hasFolia) registerScoreboards(scoreboard); - - //Reload Config File - reloadConfig(); - - //Set Language - lang = new Language(getConfig().getString("lang"), this); - - - //Rotation - coarseRot = getConfig().getDouble("coarse"); - fineRot = getConfig().getDouble("fine"); - - //Set Tool to be used in game - toolType = getConfig().getString("tool"); - if (toolType != null) { - editTool = Material.getMaterial(toolType); //Ignore Warning - } - - //Do we require a custom tool name? - requireToolName = getConfig().getBoolean("requireToolName", false); - if (requireToolName) { - editToolName = getConfig().getString("toolName", null); - if (editToolName != null) editToolName = ChatColor.translateAlternateColorCodes('&', editToolName); - } - - //Custom Model Data - allowCustomModelData = getConfig().getBoolean("allowCustomModelData", false); - - if (allowCustomModelData) { - customModelDataInt = getConfig().getInt("customModelDataInt", Integer.MIN_VALUE); - } - - //ArmorStandVisibility Node - armorStandVisibility = getConfig().getBoolean("armorStandVisibility", true); - - //Is there NBT Required for the tool - requireToolData = getConfig().getBoolean("requireToolData", false); - - if (requireToolData) { - editToolData = getConfig().getInt("toolData", Integer.MIN_VALUE); - } - - requireToolLore = getConfig().getBoolean("requireToolLore", false); - - if (requireToolLore) { - editToolLore = getConfig().getList("toolLore", null); - } - - - enablePerWorld = getConfig().getBoolean("enablePerWorldSupport", false); - if(enablePerWorld) { - allowedWorldList = getConfig().getList("allowed-worlds", null); - if (allowedWorldList != null && allowedWorldList.get(0).equals("*")) { - allowedWorldList = getServer().getWorlds().stream().map(World::getName).toList(); - } - } - - //Require Sneaking - Wolfst0rm/ArmorStandEditor#17 - requireSneaking = getConfig().getBoolean("requireSneaking", false); - - //Send Messages to Action Bar - sendToActionBar = getConfig().getBoolean("sendMessagesToActionBar", true); - - //All ItemFrame Stuff - glowItemFrames = getConfig().getBoolean("glowingItemFrame", true); - invisibleItemFrames = getConfig().getBoolean("invisibleItemFrames", true); - - //Add ability to enable ot Disable the running of the Updater - runTheUpdateChecker = getConfig().getBoolean("runTheUpdateChecker", true); - - //Ability to get Player Heads via a command - allowedToRetrievePlayerHead = getConfig().getBoolean("allowedToRetrievePlayerHead", true); - adminOnlyNotifications = getConfig().getBoolean("adminOnlyNotifications", true); - - //Add Ability to check for UpdatePerms that Notify Ops - https://github.com/Wolfieheart/ArmorStandEditor/issues/86 - opUpdateNotification = getConfig().getBoolean("opUpdateNotification", true); - updateCheckerInterval = getConfig().getDouble("updateCheckerInterval", 24); - - //Run UpdateChecker - Reports out to Console on Startup ONLY! - if (!hasFolia && runTheUpdateChecker) { - - if (opUpdateNotification) { - runUpdateCheckerWithOPNotifyOnJoinEnabled(); - } else { - runUpdateCheckerConsoleUpdateCheck(); - } - - } - } - - public static ArmorStandEditorPlugin instance() { - return instance; - } - - //Metrics/bStats Support - private void getMetrics() { - - Metrics metrics = new Metrics(this, PLUGIN_ID); - - //RequireToolLore Metric - metrics.addCustomChart(new SimplePie("tool_lore_enabled", () -> getConfig().getString("requireToolLore"))); - - //RequireToolData - metrics.addCustomChart(new SimplePie("tool_data_enabled", () -> getConfig().getString("requireToolData"))); - - //Send Messages to ActionBar - metrics.addCustomChart(new SimplePie("action_bar_messages", () -> getConfig().getString("sendMessagesToActionBar"))); - - //Check for Sneaking - metrics.addCustomChart(new SimplePie("require_sneaking", () -> getConfig().getString("requireSneaking"))); - - //Language is used - metrics.addCustomChart(new DrilldownPie("language_used", () -> { - Map> map = new HashMap<>(); - Map entry = new HashMap<>(); - - String languageUsed = getConfig().getString("lang"); - assert languageUsed != null; - - if (languageUsed.startsWith("nl")) { - map.put("Dutch", entry); - } else if (languageUsed.startsWith("de")) { - map.put("German", entry); - } else if (languageUsed.startsWith("es")) { - map.put("Spanish", entry); - } else if (languageUsed.startsWith("fr")) { - map.put("French", entry); - } else if (languageUsed.startsWith("ja")) { - map.put("Japanese", entry); - } else if (languageUsed.startsWith("pl")) { - map.put("Polish", entry); - } else if (languageUsed.startsWith("ru")) { //See PR# 41 by KPidS - map.put("Russian", entry); - } else if (languageUsed.startsWith("ro")) { - map.put("Romanian", entry); - } else if (languageUsed.startsWith("uk")) { - map.put("Ukrainian", entry); - } else if (languageUsed.startsWith("zh")) { - map.put("Chinese", entry); - } else if (languageUsed.startsWith("pt")) { - map.put("Brazilian", entry); - } else { - map.put("English", entry); - } - return map; - })); - - //ArmorStandInvis Config - metrics.addCustomChart(new SimplePie("armor_stand_invisibility_usage", () -> getConfig().getString("armorStandVisibility"))); - - //ArmorStandInvis Config - metrics.addCustomChart(new SimplePie("itemframe_invisibility_used", () -> getConfig().getString("invisibleItemFrames"))); - - //Add tracking to see who is using Custom Naming in BStats - metrics.addCustomChart(new SimplePie("custom_toolname_enabled", () -> getConfig().getString("requireToolName"))); - - metrics.addCustomChart(new SimplePie("using_the_update_checker", () -> getConfig().getString("runTheUpdateChecker"))); - metrics.addCustomChart(new SimplePie("op_updates", () -> getConfig().getString("opUpdateNotification"))); - - - } - - public NamespacedKey getIconKey() { - if (iconKey == null) iconKey = new NamespacedKey(this, "command_icon"); - return iconKey; - } - - /** - * For debugging ASE - Do not use this outside of Development or stuff - */ - public boolean isDebug() { - return debugFlag; - } - - public void debugMsgHandler(String msg){ - if(isDebug()) getServer().getLogger().log(Level.WARNING, "[ASE-DEBUG]: {0}", msg); - } } diff --git a/src/main/java/io/github/rypofalem/armorstandeditor/CommandEx.java b/src/main/java/io/github/rypofalem/armorstandeditor/CommandEx.java deleted file mode 100644 index ee1f3fb9..00000000 --- a/src/main/java/io/github/rypofalem/armorstandeditor/CommandEx.java +++ /dev/null @@ -1,628 +0,0 @@ -/* - * ArmorStandEditor: Bukkit plugin to allow editing armor stand attributes - * Copyright (C) 2016-2023 RypoFalem - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -package io.github.rypofalem.armorstandeditor; - -import com.google.gson.Gson; -import com.google.gson.JsonObject; - -import com.jeff_media.updatechecker.UpdateCheckSource; -import com.jeff_media.updatechecker.UpdateChecker; - -import com.mojang.authlib.GameProfile; -import com.mojang.authlib.properties.Property; - -import io.github.rypofalem.armorstandeditor.modes.AdjustmentMode; -import io.github.rypofalem.armorstandeditor.modes.Axis; -import io.github.rypofalem.armorstandeditor.modes.EditMode; - -import org.bukkit.Bukkit; -import org.bukkit.ChatColor; -import org.bukkit.Material; -import org.bukkit.Sound; -import org.bukkit.command.*; -import org.bukkit.entity.ArmorStand; -import org.bukkit.entity.Entity; -import org.bukkit.entity.Player; -import org.bukkit.inventory.ItemFlag; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.ItemMeta; -import org.bukkit.inventory.meta.SkullMeta; - -import java.io.IOException; -import java.io.InputStreamReader; -import java.lang.reflect.Field; -import java.net.URL; -import java.util.*; - -public class CommandEx implements CommandExecutor, TabCompleter { - ArmorStandEditorPlugin plugin; - final String LISTMODE = ChatColor.YELLOW + "/ase mode <" + Util.getEnumList(EditMode.class) + ">"; - final String LISTAXIS = ChatColor.YELLOW + "/ase axis <" + Util.getEnumList(Axis.class) + ">"; - final String LISTADJUSTMENT = ChatColor.YELLOW + "/ase adj <" + Util.getEnumList(AdjustmentMode.class) + ">"; - final String LISTSLOT = ChatColor.YELLOW + "/ase slot <1-9>"; - final String HELP = ChatColor.YELLOW + "/ase help or /ase ?"; - final String VERSION = ChatColor.YELLOW + "/ase version"; - final String UPDATE = ChatColor.YELLOW + "/ase update"; - final String RELOAD = ChatColor.YELLOW + "/ase reload"; - final String GIVECUSTOMMODEL = ChatColor.YELLOW + "/ase give"; - final String GIVEPLAYERHEAD = ChatColor.YELLOW + "/ase playerhead "; - final String GETARMORSTATS = ChatColor.YELLOW + "/ase stats"; - Gson gson = new Gson(); - - public CommandEx(ArmorStandEditorPlugin armorStandEditorPlugin) { - this.plugin = armorStandEditorPlugin; - } - - @Override - public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { - - if (sender instanceof ConsoleCommandSender) { //Fix to Support #267 - if(plugin.isDebug()) plugin.debugMsgHandler("Sender is CONSOLE!"); - if (args.length == 0) { - sender.sendMessage(VERSION); - sender.sendMessage(HELP); - sender.sendMessage(RELOAD); - } else { - switch (args[0].toLowerCase()) { - case "reload" -> commandReloadConsole(sender); - case "help", "?" -> commandHelpConsole(sender); - case "version" -> commandVersionConsole(sender); - default -> { - sender.sendMessage(plugin.getLang().getMessage("noconsolecom", "warn")); - } - } - return true; - } - - } - - if (sender instanceof Player player && !getPermissionBasic(player)) { - if(plugin.isDebug()) plugin.debugMsgHandler("Sender is Player but asedit.basic is" + getPermissionBasic(player)); - sender.sendMessage(plugin.getLang().getMessage("nopermoption", "warn", "basic")); - return true; - } else { - Player player = (Player) sender; - - if(plugin.isDebug()) plugin.debugMsgHandler("Sender is Player and asedit.basic is" + getPermissionBasic(player)); - if (args.length == 0) { - player.sendMessage(LISTMODE); - player.sendMessage(LISTAXIS); - player.sendMessage(LISTSLOT); - player.sendMessage(LISTADJUSTMENT); - player.sendMessage(VERSION); - player.sendMessage(UPDATE); - player.sendMessage(HELP); - player.sendMessage(RELOAD); - player.sendMessage(GIVECUSTOMMODEL); - player.sendMessage(GIVEPLAYERHEAD); - player.sendMessage(GETARMORSTATS); - return true; - } - switch (args[0].toLowerCase()) { - case "mode" -> commandMode(player, args); - case "axis" -> commandAxis(player, args); - case "adj" -> commandAdj(player, args); - case "slot" -> commandSlot(player, args); - case "help", "?" -> commandHelp(player); - case "version" -> commandVersion(player); - case "update" -> commandUpdate(player); - case "give" -> commandGive(player); - case "playerhead" -> commandGivePlayerHead(player, args); - case "reload" -> commandReload(player); - case "stats" -> commandStats(player); - default -> { - sender.sendMessage(LISTMODE); - sender.sendMessage(LISTAXIS); - sender.sendMessage(LISTSLOT); - sender.sendMessage(LISTADJUSTMENT); - sender.sendMessage(VERSION); - sender.sendMessage(UPDATE); - sender.sendMessage(HELP); - sender.sendMessage(RELOAD); - sender.sendMessage(GIVECUSTOMMODEL); - sender.sendMessage(GIVEPLAYERHEAD); - sender.sendMessage(GETARMORSTATS); - } - } - return true; - } - } - - // Implemented to fix: - // https://github.com/Wolfieheart/ArmorStandEditor-Issues/issues/35 & - // https://github.com/Wolfieheart/ArmorStandEditor-Issues/issues/30 - See Remarks OTHER - private void commandGive(Player player) { - if (plugin.getAllowCustomModelData() && checkPermission(player, "give", true)) { - ItemStack stack = new ItemStack(plugin.getEditTool()); //Only Support EditTool at the MOMENT - ItemMeta meta = stack.getItemMeta(); - Objects.requireNonNull(meta).setCustomModelData(plugin.getCustomModelDataInt()); - meta.setUnbreakable(true); - meta.addItemFlags(ItemFlag.HIDE_UNBREAKABLE); - stack.setItemMeta(meta); - player.getInventory().addItem(stack); - player.sendMessage(plugin.getLang().getMessage("give", "info")); - } else { - player.sendMessage(plugin.getLang().getMessage("nogive", "warn")); - } - } - - private void commandGivePlayerHead(Player player, String[] args) { - - if (plugin.getAllowedToRetrievePlayerHead() && checkPermission(player, "head", true)) { - - if (args.length == 2) { - - //Get the Player head Texture - String skinTexture = getPlayerHeadTexture(args[1]); - - if (skinTexture == null) { - player.sendMessage(plugin.getLang().getMessage("playerheaderror", "warn")); - } - - //Create the ItemStack for the PlayerHead - ItemStack playerHead = new ItemStack(Material.PLAYER_HEAD, 1); - - // Get the meta therefore - SkullMeta playerHeadMeta = (SkullMeta) playerHead.getItemMeta(); - assert playerHeadMeta != null; - - //Generate a Random UUID - GameProfile gameProfile = new GameProfile(UUID.randomUUID(), null); - gameProfile.getProperties().put("textures", new Property("textures", skinTexture)); - Field profileField = null; - - try { - profileField = playerHeadMeta.getClass().getDeclaredField("profile"); - profileField.setAccessible(true); - profileField.set(playerHeadMeta, gameProfile); - } catch (NoSuchFieldException | IllegalAccessException e) { - player.sendMessage(plugin.getLang().getMessage("playerheaderror", "warn")); - } finally { - if (profileField != null) { - profileField.setAccessible(false); - } - } - - //Set the Display Name to be that of the Player Given - playerHeadMeta.setDisplayName(args[1]); - - //Set the Item Meta - playerHead.setItemMeta(playerHeadMeta); - - //Add the head to the Players Inventory + display PlayerHead Success Message - player.getInventory().addItem(playerHead); - player.sendMessage(plugin.getLang().getMessage("playerhead", "info")); - - //Let Admins know this command has been ran - for (Player onlineList : Bukkit.getOnlinePlayers()) { - if (onlineList.hasPermission("asedit.permpack.admin") && plugin.getAdminOnlyNotifications()) { - onlineList.sendMessage(ChatColor.YELLOW + "[ArmorStandEditor] " + player.getName() + "has just used the /ase playerhead command to get the head for " + args[1]); - } - } - } - } else { - player.sendMessage(plugin.getLang().getMessage("noplayerhead", "warn")); - } - } - - private String getPlayerHeadTexture(String playerName) { - try { - // Get the UUID of the Player in Question - URL uuidURL = new URL("https://api.mojang.com/users/profiles/minecraft/" + playerName); - try (InputStreamReader uuidURLReader = new InputStreamReader(uuidURL.openStream())) { - JsonObject uuidObject = gson.fromJson(uuidURLReader, JsonObject.class); - String uuid = uuidObject.get("id").getAsString(); - - - // Get the Skin from that UUID - URL skinURL = new URL("https://sessionserver.mojang.com/session/minecraft/profile/" + uuid + "?unsigned=false"); - try (InputStreamReader skinURLReader = new InputStreamReader(skinURL.openStream())) { - JsonObject skinObject = gson.fromJson(skinURLReader, JsonObject.class); - JsonObject skinTextureProperty = skinObject.get("properties").getAsJsonArray().get(0).getAsJsonObject(); - return skinTextureProperty.get("value").getAsString(); - } - } - } catch (IOException | IllegalStateException e) { - return null; - } - } - - - private void commandSlot(Player player, String[] args) { - - if (args.length <= 1) { - player.sendMessage(plugin.getLang().getMessage("noslotnumcom", "warn")); - player.sendMessage(LISTSLOT); - } - - if (args.length > 1) { - try { - byte slot = (byte) (Byte.parseByte(args[1]) - 0b1); - if (slot >= 0 && slot < 9) { - plugin.editorManager.getPlayerEditor(player.getUniqueId()).setCopySlot(slot); - } else { - player.sendMessage(LISTSLOT); - } - - } catch (NumberFormatException nfe) { - player.sendMessage(LISTSLOT); - } - } - } - - private void commandAdj(Player player, String[] args) { - if (args.length <= 1) { - player.sendMessage(plugin.getLang().getMessage("noadjcom", "warn")); - player.sendMessage(LISTADJUSTMENT); - } - - if (args.length > 1) { - for (AdjustmentMode adj : AdjustmentMode.values()) { - if (adj.toString().toLowerCase().contentEquals(args[1].toLowerCase())) { - plugin.editorManager.getPlayerEditor(player.getUniqueId()).setAdjMode(adj); - return; - } - } - player.sendMessage(LISTADJUSTMENT); - } - } - - private void commandAxis(Player player, String[] args) { - if (args.length <= 1) { - player.sendMessage(plugin.getLang().getMessage("noaxiscom", "warn")); - player.sendMessage(LISTAXIS); - } - - if (args.length > 1) { - for (Axis axis : Axis.values()) { - if (axis.toString().toLowerCase().contentEquals(args[1].toLowerCase())) { - plugin.editorManager.getPlayerEditor(player.getUniqueId()).setAxis(axis); - return; - } - } - player.sendMessage(LISTAXIS); - } - } - - private void commandMode(Player player, String[] args) { - if (args.length <= 1) { - player.sendMessage(plugin.getLang().getMessage("nomodecom", "warn")); - player.sendMessage(LISTMODE); - } - - if (args.length > 1) { - for (EditMode mode : EditMode.values()) { - if (mode.toString().toLowerCase().contentEquals(args[1].toLowerCase())) { - if (args[1].equals("invisible") && !(checkPermission(player, "togglearmorstandvisibility", true) || plugin.getArmorStandVisibility())) return; - if (args[1].equals("itemframe") && !(checkPermission(player, "toggleitemframevisibility", true) || plugin.getItemFrameVisibility())) return; - plugin.editorManager.getPlayerEditor(player.getUniqueId()).setMode(mode); - if(plugin.isDebug()) plugin.debugMsgHandler(player.getDisplayName() + " chose the mode: " + mode); - return; - } - } - } - } - - private void commandHelp(Player player) { - player.closeInventory(); - player.playSound(player.getLocation(), Sound.ENTITY_EXPERIENCE_ORB_PICKUP, 1f, 1f); - player.sendMessage(plugin.getLang().getMessage("help", "info", plugin.editTool.name())); - player.sendMessage(""); - player.sendMessage(plugin.getLang().getMessage("helptips", "info")); - player.sendMessage(""); - player.sendRawMessage(plugin.getLang().getMessage("helpurl", "")); - player.sendRawMessage(plugin.getLang().getMessage("helpdiscord", "")); - } - - private void commandHelpConsole(CommandSender sender) { - sender.sendMessage(plugin.getLang().getMessage("help", "info", plugin.editTool.name())); - sender.sendMessage(""); - sender.sendMessage(plugin.getLang().getMessage("helptips", "info")); - sender.sendMessage(""); - sender.sendMessage(plugin.getLang().getMessage("helpurl", "info")); - sender.sendMessage(plugin.getLang().getMessage("helpdiscord", "info")); - } - - private void commandUpdate(Player player) { - if (!(checkPermission(player, "update", true))) return; - - //Only Run if the Update Command Works - if (plugin.isDebug()) plugin.debugMsgHandler("Current ArmorStandEditor Version is: " + plugin.getArmorStandEditorVersion()); - if (plugin.getArmorStandEditorVersion().contains(".x")) { - player.sendMessage(ChatColor.YELLOW + "[ArmorStandEditor] Update Checker will not work on Development Versions."); - player.sendMessage(ChatColor.YELLOW + "[ArmorStandEditor] Report all bugs to: https://github.com/Wolfieheart/ArmorStandEditor/issues"); - } else { - if (!plugin.getHasFolia() && plugin.getRunTheUpdateChecker()) { - new UpdateChecker(plugin, UpdateCheckSource.SPIGOT, "" + ArmorStandEditorPlugin.SPIGOT_RESOURCE_ID + "").checkNow(player); //Runs Update Check - } else if (plugin.getHasFolia()) { - player.sendMessage(ChatColor.YELLOW + "[ArmorStandEditor] Update Checker does not currently work on Folia."); - player.sendMessage(ChatColor.YELLOW + "[ArmorStandEditor] Report all bugs to: https://github.com/Wolfieheart/ArmorStandEditor/issues"); - } else { - player.sendMessage(ChatColor.YELLOW + "[ArmorStandEditor] Update Checker is not enabled on this server"); - } - } - } - - private void commandVersion(Player player) { - if (plugin.isDebug()) plugin.debugMsgHandler(player.getDisplayName() + " permission check for asedit.update: " + getPermissionUpdate(player)); - - if (!(getPermissionUpdate(player))) return; - String verString = plugin.getArmorStandEditorVersion(); - player.sendMessage(ChatColor.YELLOW + "[ArmorStandEditor] Version: " + verString); - } - - private void commandVersionConsole(CommandSender sender) { - String verString = plugin.getArmorStandEditorVersion(); - sender.sendMessage(ChatColor.YELLOW + "[ArmorStandEditor] Version: " + verString); - } - - private void commandReload(Player player) { - if (plugin.isDebug()) plugin.debugMsgHandler(player.getDisplayName() + " permission check for asedit.reload: " + getPermissionReload(player)); - - if (!(getPermissionReload(player))) return; - plugin.performReload(); - player.sendMessage(plugin.getLang().getMessage("reloaded", "")); - } - - private void commandReloadConsole(CommandSender sender) { - plugin.performReload(); - sender.sendMessage(plugin.getLang().getMessage("reloaded", "info")); - } - - private void commandStats(Player player) { - if (plugin.isDebug()) plugin.debugMsgHandler(player.getDisplayName() + " permission check for asedit.stats: " + getPermissionStats(player)); - - if(getPermissionStats(player)) { - for (Entity e : player.getNearbyEntities(1, 1, 1)) { - if (e instanceof ArmorStand as) { - - //Calculation TIME - Might move this out later, but is OK here for now - double headX = as.getHeadPose().getX(); - headX = Math.toDegrees(headX); - headX = Math.rint(headX); - - double headY = as.getHeadPose().getY(); - headY = Math.toDegrees(headY); - headY = Math.rint(headY); - - double headZ = as.getHeadPose().getZ(); - headZ = Math.toDegrees(headZ); - headZ = Math.rint(headZ); - - //Body - double bodyX = as.getBodyPose().getX(); - bodyX = Math.toDegrees(bodyX); - bodyX = Math.rint(bodyX); - - double bodyY = as.getBodyPose().getY(); - bodyY = Math.toDegrees(bodyY); - bodyY = Math.rint(bodyY); - - double bodyZ = as.getBodyPose().getZ(); - bodyZ = Math.toDegrees(bodyZ); - bodyZ = Math.rint(bodyZ); - - - //Arms - double rightArmX = as.getRightArmPose().getX(); - rightArmX = Math.toDegrees(rightArmX); - rightArmX = Math.rint(rightArmX); - - double rightArmY = as.getRightArmPose().getY(); - rightArmY = Math.toDegrees(rightArmY); - rightArmY = Math.rint(rightArmY); - - double rightArmZ = as.getRightArmPose().getZ(); - rightArmZ = Math.toDegrees(rightArmZ); - rightArmZ = Math.rint(rightArmZ); - - - double leftArmX = as.getLeftArmPose().getX(); - leftArmX = Math.toDegrees(leftArmX); - leftArmX = Math.rint(leftArmX); - - double leftArmY = as.getLeftArmPose().getY(); - leftArmY = Math.toDegrees(leftArmY); - leftArmY = Math.rint(leftArmY); - - double leftArmZ = as.getLeftArmPose().getZ(); - leftArmZ = Math.toDegrees(leftArmZ); - leftArmZ = Math.rint(leftArmZ); - - //Legs - double rightLegX = as.getRightLegPose().getX(); - rightLegX = Math.toDegrees(rightLegX); - rightLegX = Math.rint(rightLegX); - - double rightLegY = as.getRightLegPose().getY(); - rightLegY = Math.toDegrees(rightLegY); - rightLegY = Math.rint(rightLegY); - - double rightLegZ = as.getRightLegPose().getZ(); - rightLegZ = Math.toDegrees(rightLegZ); - rightArmX = Math.rint(rightLegZ); - - double leftLegX = as.getLeftLegPose().getX(); - leftLegX = Math.toDegrees(leftLegX); - leftLegX = Math.rint(leftLegX); - - double leftLegY = as.getLeftLegPose().getY(); - leftLegY = Math.toDegrees(leftLegY); - leftLegY = Math.rint(leftLegY); - - double leftLegZ = as.getLeftLegPose().getZ(); - leftLegZ = Math.toDegrees(leftLegZ); - leftLegZ = Math.rint(leftLegZ); - - //Coordinates - float locationX = (float) as.getLocation().getX(); - float locationY = (float) as.getLocation().getY(); - float locationZ = (float) as.getLocation().getZ(); - - //Toggles - boolean isVisible = as.isVisible(); - boolean armsVisible = as.hasArms(); - boolean basePlateVisible = as.hasBasePlate(); - boolean isVulnerable = as.isInvulnerable(); - boolean hasGravity = as.hasGravity(); - boolean isSmall = as.isSmall(); - boolean isGlowing = as.isGlowing(); - boolean isLocked = plugin.scoreboard.getTeam(plugin.lockedTeam).hasEntry(as.getUniqueId().toString()); - - player.sendMessage(ChatColor.YELLOW + "----------- Armor Stand Statistics -----------"); - player.sendMessage(ChatColor.YELLOW + plugin.getLang().getMessage("stats")); - player.sendMessage(ChatColor.YELLOW + "Head: " + ChatColor.AQUA + headX + " / " + headY + " / " + headZ); - player.sendMessage(ChatColor.YELLOW + "Body: " + ChatColor.AQUA + bodyX + " / " + bodyY + " / " + bodyZ); - player.sendMessage(ChatColor.YELLOW + "Right Arm: " + ChatColor.AQUA + rightArmX + " / " + rightArmY + " / " + rightArmZ); - player.sendMessage(ChatColor.YELLOW + "Left Arm: " + ChatColor.AQUA + leftArmX + " / " + leftArmY + " / " + leftArmZ); - player.sendMessage(ChatColor.YELLOW + "Right Leg: " + ChatColor.AQUA + rightLegX + " / " + rightLegY + " / " + rightLegZ); - player.sendMessage(ChatColor.YELLOW + "Left Leg: " + ChatColor.AQUA + leftLegX + " / " + leftLegY + " / " + leftLegZ); - player.sendMessage(ChatColor.YELLOW + "Coordinates: " + ChatColor.AQUA + " X: " + locationX + " / Y: " + locationY + " / Z: " + locationZ); - player.sendMessage(ChatColor.YELLOW + "Is Visible: " + ChatColor.AQUA + isVisible + ". " + ChatColor.YELLOW + "Arms Visible: " + ChatColor.AQUA + armsVisible + ". " + ChatColor.YELLOW + "Base Plate Visible: " + ChatColor.AQUA + basePlateVisible); - player.sendMessage(ChatColor.YELLOW + "Is Vulnerable: " + ChatColor.AQUA + isVulnerable + ". " + ChatColor.YELLOW + "Affected by Gravity: " + ChatColor.AQUA + hasGravity); - player.sendMessage(ChatColor.YELLOW + "Is Small: " + ChatColor.AQUA + isSmall + ". " + ChatColor.YELLOW + "Is Glowing: " + ChatColor.AQUA + isGlowing + ". " + ChatColor.YELLOW + "Is Locked: " + ChatColor.AQUA + isLocked); - player.sendMessage(ChatColor.YELLOW + "----------------------------------------------"); - } - } - }else{ - player.sendMessage(plugin.getLang().getMessage("norangeforstats", "warn")); - } - } - - - private boolean checkPermission(Player player, String permName, boolean sendMessageOnInvalidation) { - if (permName.equalsIgnoreCase("paste")) { - permName = "copy"; - } - if (player.hasPermission("asedit." + permName.toLowerCase())) { - return true; - } else { - if (sendMessageOnInvalidation) { - player.sendMessage(plugin.getLang().getMessage("noperm", "warn")); - } - return false; - } - } - - private boolean getPermissionBasic(Player player) { - return checkPermission(player, "basic", false); - } - private boolean getPermissionGive(Player player) { - return checkPermission(player, "give", false); - } - private boolean getPermissionUpdate(Player player) { - return checkPermission(player, "update", false); - } - private boolean getPermissionReload(Player player) { - return checkPermission(player, "reload", false); - } - private boolean getPermissionPlayerHead(Player player) { - return checkPermission(player, "head", false); - } - private boolean getPermissionStats(Player player) { - return checkPermission(player, "stats", false); - } - - //REFACTOR COMPLETION - @Override - public List onTabComplete(CommandSender sender, Command command, String label, String[] args) { - List argList = new ArrayList<>(); - Player player = (Player) sender; - - if (isCommandValid(command.getName())) { - - if (args.length == 1) { - argList.add("mode"); - argList.add("axis"); - argList.add("adj"); - argList.add("slot"); - argList.add("help"); - argList.add("?"); - - //Will Only work with permissions - if (getPermissionGive(player)) { - argList.add("give"); - } - if (getPermissionUpdate(player)) { - argList.add("update"); - } - if (getPermissionReload(player)) { - argList.add("reload"); - } - if (getPermissionPlayerHead(player) && plugin.getAllowedToRetrievePlayerHead()) { - argList.add("playerhead"); - } - - if (getPermissionStats(player)){ - argList.add("stats"); - } - } - - if (args.length == 2 && args[0].equalsIgnoreCase("mode")) { - argList.addAll(getModeOptions()); - } - - if (args.length == 2 && args[0].equalsIgnoreCase("axis")) { - argList.addAll(getAxisOptions()); - } - - if (args.length == 2 && args[0].equalsIgnoreCase("slot")) { - argList.addAll(getSlotOptions()); - } - - if (args.length == 2 && args[0].equalsIgnoreCase("adj")) { - argList.addAll(getAdjOptions()); - } - - return argList.stream().filter(a -> a.startsWith(args[0])).toList(); - } - - return Collections.emptyList(); - } - - private boolean isCommandValid(String commandName) { - return commandName.equalsIgnoreCase("ase") || - commandName.equalsIgnoreCase("armorstandeditor") || - commandName.equalsIgnoreCase("asedit"); - } - - private List getModeOptions() { - return List.of( - "None", "Invisible", "ShowArms", "Gravity", "BasePlate", - "Size", "Copy", "Paste", "Head", "Body", "LeftArm", - "RightArm", "LeftLeg", "RightLeg", "Placement", - "DisableSlots", "Rotate", "Equipment", "Reset", - "ItemFrame", "ItemFrameGlow", "Vulnerability", "ArmorStandGlow" - ); - } - - private List getAxisOptions() { - return List.of("X", "Y", "Z"); - } - - private List getSlotOptions() { - return List.of("0", "1", "2", "3", "4", "5", "6", "7", "8", "9"); - } - - private List getAdjOptions() { - return List.of("Coarse", "Fine"); - } - -} \ No newline at end of file diff --git a/src/main/java/io/github/rypofalem/armorstandeditor/Metrics.java b/src/main/java/io/github/rypofalem/armorstandeditor/Metrics.java deleted file mode 100644 index a842cfab..00000000 --- a/src/main/java/io/github/rypofalem/armorstandeditor/Metrics.java +++ /dev/null @@ -1,881 +0,0 @@ -/* - * This Metrics class was auto-generated and can be copied into your project if you are - * not using a build tool like Gradle or Maven for dependency management. - * - * IMPORTANT: You are not allowed to modify this class, except changing the package. - * - * Disallowed modifications include but are not limited to: - * - Remove the option for users to opt-out - * - Change the frequency for data submission - * - Obfuscate the code (every obfuscator should allow you to make an exception for specific files) - * - Reformat the code (if you use a linter, add an exception) - * - * Violations will result in a ban of your plugin and account from bStats. - */ -package io.github.rypofalem.armorstandeditor; - -import java.io.BufferedReader; -import java.io.ByteArrayOutputStream; -import java.io.DataOutputStream; -import java.io.File; -import java.io.IOException; -import java.io.InputStreamReader; -import java.lang.reflect.Method; -import java.net.URL; -import java.nio.charset.StandardCharsets; -import java.util.Arrays; -import java.util.Collection; -import java.util.HashSet; -import java.util.Map; -import java.util.Objects; -import java.util.Set; -import java.util.UUID; -import java.util.concurrent.Callable; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.ScheduledThreadPoolExecutor; -import java.util.concurrent.TimeUnit; -import java.util.function.BiConsumer; -import java.util.function.Consumer; -import java.util.function.Supplier; -import java.util.logging.Level; -import java.util.stream.Collectors; -import java.util.zip.GZIPOutputStream; -import javax.net.ssl.HttpsURLConnection; -import org.bukkit.Bukkit; -import org.bukkit.configuration.file.YamlConfiguration; -import org.bukkit.entity.Player; -import org.bukkit.plugin.Plugin; -import org.bukkit.plugin.java.JavaPlugin; - -public class Metrics { - - private final Plugin plugin; - - private final MetricsBase metricsBase; - - /** - * Creates a new Metrics instance. - * - * @param plugin Your plugin instance. - * @param serviceId The id of the service. It can be found at What is my plugin id? - */ - public Metrics(JavaPlugin plugin, int serviceId) { - this.plugin = plugin; - // Get the config file - File bStatsFolder = new File(plugin.getDataFolder().getParentFile(), "bStats"); - File configFile = new File(bStatsFolder, "config.yml"); - YamlConfiguration config = YamlConfiguration.loadConfiguration(configFile); - if (!config.isSet("serverUuid")) { - config.addDefault("enabled", true); - config.addDefault("serverUuid", UUID.randomUUID().toString()); - config.addDefault("logFailedRequests", false); - config.addDefault("logSentData", false); - config.addDefault("logResponseStatusText", false); - // Inform the server owners about bStats - config - .options() - .header( - "bStats (https://bStats.org) collects some basic information for plugin authors, like how\n" - + "many people use their plugin and their total player count. It's recommended to keep bStats\n" - + "enabled, but if you're not comfortable with this, you can turn this setting off. There is no\n" - + "performance penalty associated with having metrics enabled, and data sent to bStats is fully\n" - + "anonymous.") - .copyDefaults(true); - try { - config.save(configFile); - } catch (IOException ignored) { - } - } - // Load the data - boolean enabled = config.getBoolean("enabled", true); - String serverUUID = config.getString("serverUuid"); - boolean logErrors = config.getBoolean("logFailedRequests", false); - boolean logSentData = config.getBoolean("logSentData", false); - boolean logResponseStatusText = config.getBoolean("logResponseStatusText", false); - metricsBase = - new MetricsBase( - "bukkit", - serverUUID, - serviceId, - enabled, - this::appendPlatformData, - this::appendServiceData, - submitDataTask -> Bukkit.getScheduler().runTask(plugin, submitDataTask), - plugin::isEnabled, - (message, error) -> this.plugin.getLogger().log(Level.WARNING, message, error), - (message) -> this.plugin.getLogger().log(Level.INFO, message), - logErrors, - logSentData, - logResponseStatusText); - } - - /** Shuts down the underlying scheduler service. */ - public void shutdown() { - metricsBase.shutdown(); - } - - /** - * Adds a custom chart. - * - * @param chart The chart to add. - */ - public void addCustomChart(CustomChart chart) { - metricsBase.addCustomChart(chart); - } - - private void appendPlatformData(JsonObjectBuilder builder) { - builder.appendField("playerAmount", getPlayerAmount()); - builder.appendField("onlineMode", Bukkit.getOnlineMode() ? 1 : 0); - builder.appendField("bukkitVersion", Bukkit.getVersion()); - builder.appendField("bukkitName", Bukkit.getName()); - builder.appendField("javaVersion", System.getProperty("java.version")); - builder.appendField("osName", System.getProperty("os.name")); - builder.appendField("osArch", System.getProperty("os.arch")); - builder.appendField("osVersion", System.getProperty("os.version")); - builder.appendField("coreCount", Runtime.getRuntime().availableProcessors()); - } - - private void appendServiceData(JsonObjectBuilder builder) { - builder.appendField("pluginVersion", plugin.getDescription().getVersion()); - } - - private int getPlayerAmount() { - try { - // Around MC 1.8 the return type was changed from an array to a collection, - // This fixes java.lang.NoSuchMethodError: - // org.bukkit.Bukkit.getOnlinePlayers()Ljava/util/Collection; - Method onlinePlayersMethod = Class.forName("org.bukkit.Server").getMethod("getOnlinePlayers"); - return onlinePlayersMethod.getReturnType().equals(Collection.class) - ? ((Collection) onlinePlayersMethod.invoke(Bukkit.getServer())).size() - : ((Player[]) onlinePlayersMethod.invoke(Bukkit.getServer())).length; - } catch (Exception e) { - // Just use the new method if the reflection failed - return Bukkit.getOnlinePlayers().size(); - } - } - - public static class MetricsBase { - - /** The version of the Metrics class. */ - public static final String METRICS_VERSION = "3.0.2"; - - private static final String REPORT_URL = "https://bStats.org/api/v2/data/%s"; - - private final ScheduledExecutorService scheduler; - - private final String platform; - - private final String serverUuid; - - private final int serviceId; - - private final Consumer appendPlatformDataConsumer; - - private final Consumer appendServiceDataConsumer; - - private final Consumer submitTaskConsumer; - - private final Supplier checkServiceEnabledSupplier; - - private final BiConsumer errorLogger; - - private final Consumer infoLogger; - - private final boolean logErrors; - - private final boolean logSentData; - - private final boolean logResponseStatusText; - - private final Set customCharts = new HashSet<>(); - - private final boolean enabled; - - /** - * Creates a new MetricsBase class instance. - * - * @param platform The platform of the service. - * @param serviceId The id of the service. - * @param serverUuid The server uuid. - * @param enabled Whether or not data sending is enabled. - * @param appendPlatformDataConsumer A consumer that receives a {@code JsonObjectBuilder} and - * appends all platform-specific data. - * @param appendServiceDataConsumer A consumer that receives a {@code JsonObjectBuilder} and - * appends all service-specific data. - * @param submitTaskConsumer A consumer that takes a runnable with the submit task. This can be - * used to delegate the data collection to a another thread to prevent errors caused by - * concurrency. Can be {@code null}. - * @param checkServiceEnabledSupplier A supplier to check if the service is still enabled. - * @param errorLogger A consumer that accepts log message and an error. - * @param infoLogger A consumer that accepts info log messages. - * @param logErrors Whether or not errors should be logged. - * @param logSentData Whether or not the sent data should be logged. - * @param logResponseStatusText Whether or not the response status text should be logged. - */ - public MetricsBase( - String platform, - String serverUuid, - int serviceId, - boolean enabled, - Consumer appendPlatformDataConsumer, - Consumer appendServiceDataConsumer, - Consumer submitTaskConsumer, - Supplier checkServiceEnabledSupplier, - BiConsumer errorLogger, - Consumer infoLogger, - boolean logErrors, - boolean logSentData, - boolean logResponseStatusText) { - ScheduledThreadPoolExecutor scheduler = - new ScheduledThreadPoolExecutor(1, task -> new Thread(task, "bStats-Metrics")); - // We want delayed tasks (non-periodic) that will execute in the future to be - // cancelled when the scheduler is shutdown. - // Otherwise, we risk preventing the server from shutting down even when - // MetricsBase#shutdown() is called - scheduler.setExecuteExistingDelayedTasksAfterShutdownPolicy(false); - this.scheduler = scheduler; - this.platform = platform; - this.serverUuid = serverUuid; - this.serviceId = serviceId; - this.enabled = enabled; - this.appendPlatformDataConsumer = appendPlatformDataConsumer; - this.appendServiceDataConsumer = appendServiceDataConsumer; - this.submitTaskConsumer = submitTaskConsumer; - this.checkServiceEnabledSupplier = checkServiceEnabledSupplier; - this.errorLogger = errorLogger; - this.infoLogger = infoLogger; - this.logErrors = logErrors; - this.logSentData = logSentData; - this.logResponseStatusText = logResponseStatusText; - checkRelocation(); - if (enabled) { - // WARNING: Removing the option to opt-out will get your plugin banned from - // bStats - startSubmitting(); - } - } - - public void addCustomChart(CustomChart chart) { - this.customCharts.add(chart); - } - - public void shutdown() { - scheduler.shutdown(); - } - - private void startSubmitting() { - final Runnable submitTask = - () -> { - if (!enabled || !checkServiceEnabledSupplier.get()) { - // Submitting data or service is disabled - scheduler.shutdown(); - return; - } - if (submitTaskConsumer != null) { - submitTaskConsumer.accept(this::submitData); - } else { - this.submitData(); - } - }; - // Many servers tend to restart at a fixed time at xx:00 which causes an uneven - // distribution of requests on the - // bStats backend. To circumvent this problem, we introduce some randomness into - // the initial and second delay. - // WARNING: You must not modify and part of this Metrics class, including the - // submit delay or frequency! - // WARNING: Modifying this code will get your plugin banned on bStats. Just - // don't do it! - long initialDelay = (long) (1000 * 60 * (3 + Math.random() * 3)); - long secondDelay = (long) (1000 * 60 * (Math.random() * 30)); - scheduler.schedule(submitTask, initialDelay, TimeUnit.MILLISECONDS); - scheduler.scheduleAtFixedRate( - submitTask, initialDelay + secondDelay, 1000 * 60 * 30, TimeUnit.MILLISECONDS); - } - - private void submitData() { - final JsonObjectBuilder baseJsonBuilder = new JsonObjectBuilder(); - appendPlatformDataConsumer.accept(baseJsonBuilder); - final JsonObjectBuilder serviceJsonBuilder = new JsonObjectBuilder(); - appendServiceDataConsumer.accept(serviceJsonBuilder); - JsonObjectBuilder.JsonObject[] chartData = - customCharts.stream() - .map(customChart -> customChart.getRequestJsonObject(errorLogger, logErrors)) - .filter(Objects::nonNull) - .toArray(JsonObjectBuilder.JsonObject[]::new); - serviceJsonBuilder.appendField("id", serviceId); - serviceJsonBuilder.appendField("customCharts", chartData); - baseJsonBuilder.appendField("service", serviceJsonBuilder.build()); - baseJsonBuilder.appendField("serverUUID", serverUuid); - baseJsonBuilder.appendField("metricsVersion", METRICS_VERSION); - JsonObjectBuilder.JsonObject data = baseJsonBuilder.build(); - scheduler.execute( - () -> { - try { - // Send the data - sendData(data); - } catch (Exception e) { - // Something went wrong! :( - if (logErrors) { - errorLogger.accept("Could not submit bStats metrics data", e); - } - } - }); - } - - private void sendData(JsonObjectBuilder.JsonObject data) throws Exception { - if (logSentData) { - infoLogger.accept("Sent bStats metrics data: " + data.toString()); - } - String url = String.format(REPORT_URL, platform); - HttpsURLConnection connection = (HttpsURLConnection) new URL(url).openConnection(); - // Compress the data to save bandwidth - byte[] compressedData = compress(data.toString()); - connection.setRequestMethod("POST"); - connection.addRequestProperty("Accept", "application/json"); - connection.addRequestProperty("Connection", "close"); - connection.addRequestProperty("Content-Encoding", "gzip"); - connection.addRequestProperty("Content-Length", String.valueOf(compressedData.length)); - connection.setRequestProperty("Content-Type", "application/json"); - connection.setRequestProperty("User-Agent", "Metrics-Service/1"); - connection.setDoOutput(true); - try (DataOutputStream outputStream = new DataOutputStream(connection.getOutputStream())) { - outputStream.write(compressedData); - } - StringBuilder builder = new StringBuilder(); - try (BufferedReader bufferedReader = - new BufferedReader(new InputStreamReader(connection.getInputStream()))) { - String line; - while ((line = bufferedReader.readLine()) != null) { - builder.append(line); - } - } - if (logResponseStatusText) { - infoLogger.accept("Sent data to bStats and received response: " + builder); - } - } - - /** Checks that the class was properly relocated. */ - private void checkRelocation() { - // You can use the property to disable the check in your test environment - if (System.getProperty("bstats.relocatecheck") == null - || !System.getProperty("bstats.relocatecheck").equals("false")) { - // Maven's Relocate is clever and changes strings, too. So we have to use this - // little "trick" ... :D - final String defaultPackage = - new String(new byte[] {'o', 'r', 'g', '.', 'b', 's', 't', 'a', 't', 's'}); - final String examplePackage = - new String(new byte[] {'y', 'o', 'u', 'r', '.', 'p', 'a', 'c', 'k', 'a', 'g', 'e'}); - // We want to make sure no one just copy & pastes the example and uses the wrong - // package names - if (MetricsBase.class.getPackage().getName().startsWith(defaultPackage) - || MetricsBase.class.getPackage().getName().startsWith(examplePackage)) { - throw new IllegalStateException("bStats Metrics class has not been relocated correctly!"); - } - } - } - - /** - * Gzips the given string. - * - * @param str The string to gzip. - * @return The gzipped string. - */ - private static byte[] compress(final String str) throws IOException { - if (str == null) { - return null; - } - ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); - try (GZIPOutputStream gzip = new GZIPOutputStream(outputStream)) { - gzip.write(str.getBytes(StandardCharsets.UTF_8)); - } - return outputStream.toByteArray(); - } - } - - public static class SimplePie extends CustomChart { - - private final Callable callable; - - /** - * Class constructor. - * - * @param chartId The id of the chart. - * @param callable The callable which is used to request the chart data. - */ - public SimplePie(String chartId, Callable callable) { - super(chartId); - this.callable = callable; - } - - @Override - protected JsonObjectBuilder.JsonObject getChartData() throws Exception { - String value = callable.call(); - if (value == null || value.isEmpty()) { - // Null = skip the chart - return null; - } - return new JsonObjectBuilder().appendField("value", value).build(); - } - } - - public static class MultiLineChart extends CustomChart { - - private final Callable> callable; - - /** - * Class constructor. - * - * @param chartId The id of the chart. - * @param callable The callable which is used to request the chart data. - */ - public MultiLineChart(String chartId, Callable> callable) { - super(chartId); - this.callable = callable; - } - - @Override - protected JsonObjectBuilder.JsonObject getChartData() throws Exception { - JsonObjectBuilder valuesBuilder = new JsonObjectBuilder(); - Map map = callable.call(); - if (map == null || map.isEmpty()) { - // Null = skip the chart - return null; - } - boolean allSkipped = true; - for (Map.Entry entry : map.entrySet()) { - if (entry.getValue() == 0) { - // Skip this invalid - continue; - } - allSkipped = false; - valuesBuilder.appendField(entry.getKey(), entry.getValue()); - } - if (allSkipped) { - // Null = skip the chart - return null; - } - return new JsonObjectBuilder().appendField("values", valuesBuilder.build()).build(); - } - } - - public static class AdvancedPie extends CustomChart { - - private final Callable> callable; - - /** - * Class constructor. - * - * @param chartId The id of the chart. - * @param callable The callable which is used to request the chart data. - */ - public AdvancedPie(String chartId, Callable> callable) { - super(chartId); - this.callable = callable; - } - - @Override - protected JsonObjectBuilder.JsonObject getChartData() throws Exception { - JsonObjectBuilder valuesBuilder = new JsonObjectBuilder(); - Map map = callable.call(); - if (map == null || map.isEmpty()) { - // Null = skip the chart - return null; - } - boolean allSkipped = true; - for (Map.Entry entry : map.entrySet()) { - if (entry.getValue() == 0) { - // Skip this invalid - continue; - } - allSkipped = false; - valuesBuilder.appendField(entry.getKey(), entry.getValue()); - } - if (allSkipped) { - // Null = skip the chart - return null; - } - return new JsonObjectBuilder().appendField("values", valuesBuilder.build()).build(); - } - } - - public static class SimpleBarChart extends CustomChart { - - private final Callable> callable; - - /** - * Class constructor. - * - * @param chartId The id of the chart. - * @param callable The callable which is used to request the chart data. - */ - public SimpleBarChart(String chartId, Callable> callable) { - super(chartId); - this.callable = callable; - } - - @Override - protected JsonObjectBuilder.JsonObject getChartData() throws Exception { - JsonObjectBuilder valuesBuilder = new JsonObjectBuilder(); - Map map = callable.call(); - if (map == null || map.isEmpty()) { - // Null = skip the chart - return null; - } - for (Map.Entry entry : map.entrySet()) { - valuesBuilder.appendField(entry.getKey(), new int[] {entry.getValue()}); - } - return new JsonObjectBuilder().appendField("values", valuesBuilder.build()).build(); - } - } - - public static class AdvancedBarChart extends CustomChart { - - private final Callable> callable; - - /** - * Class constructor. - * - * @param chartId The id of the chart. - * @param callable The callable which is used to request the chart data. - */ - public AdvancedBarChart(String chartId, Callable> callable) { - super(chartId); - this.callable = callable; - } - - @Override - protected JsonObjectBuilder.JsonObject getChartData() throws Exception { - JsonObjectBuilder valuesBuilder = new JsonObjectBuilder(); - Map map = callable.call(); - if (map == null || map.isEmpty()) { - // Null = skip the chart - return null; - } - boolean allSkipped = true; - for (Map.Entry entry : map.entrySet()) { - if (entry.getValue().length == 0) { - // Skip this invalid - continue; - } - allSkipped = false; - valuesBuilder.appendField(entry.getKey(), entry.getValue()); - } - if (allSkipped) { - // Null = skip the chart - return null; - } - return new JsonObjectBuilder().appendField("values", valuesBuilder.build()).build(); - } - } - - public static class DrilldownPie extends CustomChart { - - private final Callable>> callable; - - /** - * Class constructor. - * - * @param chartId The id of the chart. - * @param callable The callable which is used to request the chart data. - */ - public DrilldownPie(String chartId, Callable>> callable) { - super(chartId); - this.callable = callable; - } - - @Override - public JsonObjectBuilder.JsonObject getChartData() throws Exception { - JsonObjectBuilder valuesBuilder = new JsonObjectBuilder(); - Map> map = callable.call(); - if (map == null || map.isEmpty()) { - // Null = skip the chart - return null; - } - boolean reallyAllSkipped = true; - for (Map.Entry> entryValues : map.entrySet()) { - JsonObjectBuilder valueBuilder = new JsonObjectBuilder(); - boolean allSkipped = true; - for (Map.Entry valueEntry : map.get(entryValues.getKey()).entrySet()) { - valueBuilder.appendField(valueEntry.getKey(), valueEntry.getValue()); - allSkipped = false; - } - if (!allSkipped) { - reallyAllSkipped = false; - valuesBuilder.appendField(entryValues.getKey(), valueBuilder.build()); - } - } - if (reallyAllSkipped) { - // Null = skip the chart - return null; - } - return new JsonObjectBuilder().appendField("values", valuesBuilder.build()).build(); - } - } - - public abstract static class CustomChart { - - private final String chartId; - - protected CustomChart(String chartId) { - if (chartId == null) { - throw new IllegalArgumentException("chartId must not be null"); - } - this.chartId = chartId; - } - - public JsonObjectBuilder.JsonObject getRequestJsonObject( - BiConsumer errorLogger, boolean logErrors) { - JsonObjectBuilder builder = new JsonObjectBuilder(); - builder.appendField("chartId", chartId); - try { - JsonObjectBuilder.JsonObject data = getChartData(); - if (data == null) { - // If the data is null we don't send the chart. - return null; - } - builder.appendField("data", data); - } catch (Throwable t) { - if (logErrors) { - errorLogger.accept("Failed to get data for custom chart with id " + chartId, t); - } - return null; - } - return builder.build(); - } - - protected abstract JsonObjectBuilder.JsonObject getChartData() throws Exception; - } - - public static class SingleLineChart extends CustomChart { - - private final Callable callable; - - /** - * Class constructor. - * - * @param chartId The id of the chart. - * @param callable The callable which is used to request the chart data. - */ - public SingleLineChart(String chartId, Callable callable) { - super(chartId); - this.callable = callable; - } - - @Override - protected JsonObjectBuilder.JsonObject getChartData() throws Exception { - int value = callable.call(); - if (value == 0) { - // Null = skip the chart - return null; - } - return new JsonObjectBuilder().appendField("value", value).build(); - } - } - - /** - * An extremely simple JSON builder. - * - *

While this class is neither feature-rich nor the most performant one, it's sufficient enough - * for its use-case. - */ - public static class JsonObjectBuilder { - - private StringBuilder builder = new StringBuilder(); - - private boolean hasAtLeastOneField = false; - - public JsonObjectBuilder() { - builder.append("{"); - } - - /** - * Appends a null field to the JSON. - * - * @param key The key of the field. - * @return A reference to this object. - */ - public JsonObjectBuilder appendNull(String key) { - appendFieldUnescaped(key, "null"); - return this; - } - - /** - * Appends a string field to the JSON. - * - * @param key The key of the field. - * @param value The value of the field. - * @return A reference to this object. - */ - public JsonObjectBuilder appendField(String key, String value) { - if (value == null) { - throw new IllegalArgumentException("JSON value must not be null"); - } - appendFieldUnescaped(key, "\"" + escape(value) + "\""); - return this; - } - - /** - * Appends an integer field to the JSON. - * - * @param key The key of the field. - * @param value The value of the field. - * @return A reference to this object. - */ - public JsonObjectBuilder appendField(String key, int value) { - appendFieldUnescaped(key, String.valueOf(value)); - return this; - } - - /** - * Appends an object to the JSON. - * - * @param key The key of the field. - * @param object The object. - * @return A reference to this object. - */ - public JsonObjectBuilder appendField(String key, JsonObject object) { - if (object == null) { - throw new IllegalArgumentException("JSON object must not be null"); - } - appendFieldUnescaped(key, object.toString()); - return this; - } - - /** - * Appends a string array to the JSON. - * - * @param key The key of the field. - * @param values The string array. - * @return A reference to this object. - */ - public JsonObjectBuilder appendField(String key, String[] values) { - if (values == null) { - throw new IllegalArgumentException("JSON values must not be null"); - } - String escapedValues = - Arrays.stream(values) - .map(value -> "\"" + escape(value) + "\"") - .collect(Collectors.joining(",")); - appendFieldUnescaped(key, "[" + escapedValues + "]"); - return this; - } - - /** - * Appends an integer array to the JSON. - * - * @param key The key of the field. - * @param values The integer array. - * @return A reference to this object. - */ - public JsonObjectBuilder appendField(String key, int[] values) { - if (values == null) { - throw new IllegalArgumentException("JSON values must not be null"); - } - String escapedValues = - Arrays.stream(values).mapToObj(String::valueOf).collect(Collectors.joining(",")); - appendFieldUnescaped(key, "[" + escapedValues + "]"); - return this; - } - - /** - * Appends an object array to the JSON. - * - * @param key The key of the field. - * @param values The integer array. - * @return A reference to this object. - */ - public JsonObjectBuilder appendField(String key, JsonObject[] values) { - if (values == null) { - throw new IllegalArgumentException("JSON values must not be null"); - } - String escapedValues = - Arrays.stream(values).map(JsonObject::toString).collect(Collectors.joining(",")); - appendFieldUnescaped(key, "[" + escapedValues + "]"); - return this; - } - - /** - * Appends a field to the object. - * - * @param key The key of the field. - * @param escapedValue The escaped value of the field. - */ - private void appendFieldUnescaped(String key, String escapedValue) { - if (builder == null) { - throw new IllegalStateException("JSON has already been built"); - } - if (key == null) { - throw new IllegalArgumentException("JSON key must not be null"); - } - if (hasAtLeastOneField) { - builder.append(","); - } - builder.append("\"").append(escape(key)).append("\":").append(escapedValue); - hasAtLeastOneField = true; - } - - /** - * Builds the JSON string and invalidates this builder. - * - * @return The built JSON string. - */ - public JsonObject build() { - if (builder == null) { - throw new IllegalStateException("JSON has already been built"); - } - JsonObject object = new JsonObject(builder.append("}").toString()); - builder = null; - return object; - } - - /** - * Escapes the given string like stated in https://www.ietf.org/rfc/rfc4627.txt. - * - *

This method escapes only the necessary characters '"', '\'. and '\u0000' - '\u001F'. - * Compact escapes are not used (e.g., '\n' is escaped as "\u000a" and not as "\n"). - * - * @param value The value to escape. - * @return The escaped value. - */ - private static String escape(String value) { - final StringBuilder builder = new StringBuilder(); - for (int i = 0; i < value.length(); i++) { - char c = value.charAt(i); - if (c == '"') { - builder.append("\\\""); - } else if (c == '\\') { - builder.append("\\\\"); - } else if (c <= '\u000F') { - builder.append("\\u000").append(Integer.toHexString(c)); - } else if (c <= '\u001F') { - builder.append("\\u00").append(Integer.toHexString(c)); - } else { - builder.append(c); - } - } - return builder.toString(); - } - - /** - * A super simple representation of a JSON object. - * - *

This class only exists to make methods of the {@link JsonObjectBuilder} type-safe and not - * allow a raw string inputs for methods like {@link JsonObjectBuilder#appendField(String, - * JsonObject)}. - */ - public static class JsonObject { - - private final String value; - - private JsonObject(String value) { - this.value = value; - } - - @Override - public String toString() { - return value; - } - } - } -} \ No newline at end of file diff --git a/src/main/java/io/github/rypofalem/armorstandeditor/PlayerEditor.java b/src/main/java/io/github/rypofalem/armorstandeditor/PlayerEditor.java deleted file mode 100644 index 9d26c0e7..00000000 --- a/src/main/java/io/github/rypofalem/armorstandeditor/PlayerEditor.java +++ /dev/null @@ -1,684 +0,0 @@ -/* - * ArmorStandEditor: Bukkit plugin to allow editing armor stand attributes - * Copyright (C) 2016-2023 RypoFalem - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package io.github.rypofalem.armorstandeditor; - -import io.github.rypofalem.armorstandeditor.menu.PresetArmorPosesMenu; -import net.md_5.bungee.api.ChatMessageType; -import net.md_5.bungee.api.chat.TextComponent; - -import io.github.rypofalem.armorstandeditor.api.*; -import io.github.rypofalem.armorstandeditor.menu.EquipmentMenu; -import io.github.rypofalem.armorstandeditor.menu.Menu; -import io.github.rypofalem.armorstandeditor.modes.AdjustmentMode; -import io.github.rypofalem.armorstandeditor.modes.ArmorStandData; -import io.github.rypofalem.armorstandeditor.modes.Axis; -import io.github.rypofalem.armorstandeditor.modes.CopySlots; -import io.github.rypofalem.armorstandeditor.modes.EditMode; - -import org.bukkit.*; -import org.bukkit.entity.ArmorStand; -import org.bukkit.entity.ItemFrame; -import org.bukkit.entity.Player; -import org.bukkit.inventory.EquipmentSlot; -import org.bukkit.potion.PotionEffect; -import org.bukkit.potion.PotionEffectType; -import org.bukkit.scoreboard.Team; -import org.bukkit.util.EulerAngle; - -import java.util.ArrayList; -import java.util.UUID; - -public class PlayerEditor { - public ArmorStandEditorPlugin plugin; - Team team; - private UUID uuid; - UUID armorStandID; - EditMode eMode; - AdjustmentMode adjMode; - CopySlots copySlots; - Axis axis; - double eulerAngleChange; - double degreeAngleChange; - double movChange; - Menu chestMenu; - ArmorStand target; - ArrayList targetList = null; - - //NEW: ItemFrame Stuff - ItemFrame frameTarget; - ArrayList frameTargetList = null; - int targetIndex = 0; - int frameTargetIndex = 0; - EquipmentMenu equipMenu; - PresetArmorPosesMenu presetPoseMenu; - long lastCancelled = 0; - - public PlayerEditor(UUID uuid, ArmorStandEditorPlugin plugin) { - this.uuid = uuid; - this.plugin = plugin; - eMode = EditMode.NONE; - adjMode = AdjustmentMode.COARSE; - axis = Axis.X; - copySlots = new CopySlots(); - eulerAngleChange = getManager().coarseAdj; - degreeAngleChange = eulerAngleChange / Math.PI * 180; - movChange = getManager().coarseMov; - chestMenu = new Menu(this); - } - - public void setMode(EditMode editMode) { - this.eMode = editMode; - sendMessage("setmode", editMode.toString().toLowerCase()); - } - - public void setAxis(Axis axis) { - this.axis = axis; - sendMessage("setaxis", axis.toString().toLowerCase()); - } - - public void setAdjMode(AdjustmentMode adjMode) { - this.adjMode = adjMode; - if (adjMode == AdjustmentMode.COARSE) { - eulerAngleChange = getManager().coarseAdj; - movChange = getManager().coarseMov; - } else { - eulerAngleChange = getManager().fineAdj; - movChange = getManager().fineMov; - } - degreeAngleChange = eulerAngleChange / Math.PI * 180; - sendMessage("setadj", adjMode.toString().toLowerCase()); - } - - public void setCopySlot(byte slot) { - copySlots.changeSlots(slot); - sendMessage("setslot", String.valueOf((slot + 1))); - } - - public void editArmorStand(ArmorStand armorStand) { - if (getPlayer().hasPermission("asedit.basic")) { - - armorStand = attemptTarget(armorStand); - switch (eMode) { - case LEFTARM: - armorStand.setLeftArmPose(subEulerAngle(armorStand.getLeftArmPose())); - break; - case RIGHTARM: - armorStand.setRightArmPose(subEulerAngle(armorStand.getRightArmPose())); - break; - case BODY: - armorStand.setBodyPose(subEulerAngle(armorStand.getBodyPose())); - break; - case HEAD: - armorStand.setHeadPose(subEulerAngle(armorStand.getHeadPose())); - break; - case LEFTLEG: - armorStand.setLeftLegPose(subEulerAngle(armorStand.getLeftLegPose())); - break; - case RIGHTLEG: - armorStand.setRightLegPose(subEulerAngle(armorStand.getRightLegPose())); - break; - case SHOWARMS: - toggleArms(armorStand); - break; - case SIZE: - toggleSize(armorStand); - break; - case INVISIBLE: - toggleVisible(armorStand); - break; - case BASEPLATE: - togglePlate(armorStand); - break; - case GRAVITY: - toggleGravity(armorStand); - break; - case COPY: - copy(armorStand); - break; - case PASTE: - paste(armorStand); - break; - case PLACEMENT: - move(armorStand); - break; - case ROTATE: - rotate(armorStand); - break; - case DISABLESLOTS: - toggleDisableSlots(armorStand); - break; - case VULNERABILITY: - toggleInvulnerability(armorStand); - break; - case EQUIPMENT: - openEquipment(armorStand); - break; - case RESET: - resetPosition(armorStand); - break; - case GLOWING: - toggleGlowing(armorStand); - break; - case PRESET: - choosePreset(armorStand); - break; - case NONE: - default: - sendMessage("nomode", null); - break; - - } - }else return; - } - - public void editItemFrame(ItemFrame itemFrame) { - if (getPlayer().hasPermission("asedit.toggleitemframevisibility") || plugin.invisibleItemFrames) { - - //Generate a new ArmorStandManipulationEvent and call it out. - ItemFrameManipulatedEvent event = new ItemFrameManipulatedEvent(itemFrame, getPlayer()); - Bukkit.getPluginManager().callEvent(event); // Bukkit handles the call out - if (event.isCancelled()) return; //do nothing if cancelled - - switch (eMode) { - case ITEMFRAME: - toggleItemFrameVisible(itemFrame); - break; - case RESET: - itemFrame.setVisible(true); - break; - case NONE: - default: - sendMessage("nomodeif", null); - break; - } - }else return; - } - - private void openEquipment(ArmorStand armorStand) { - if (!getPlayer().hasPermission("asedit.equipment")) return; - //if (team != null && team.hasEntry(armorStand.getName())) return; //Do not allow editing if the ArmorStand is Disabled - equipMenu = new EquipmentMenu(this, armorStand); - equipMenu.open(); - } - - private void choosePreset(ArmorStand armorStand){ - if (!getPlayer().hasPermission("asedit.basic")) return; - presetPoseMenu = new PresetArmorPosesMenu(this, armorStand); - presetPoseMenu.openMenu(); - } - - public void reverseEditArmorStand(ArmorStand armorStand) { - if (!getPlayer().hasPermission("asedit.basic")) return; - - //Generate a new ArmorStandManipulationEvent and call it out. - ArmorStandManipulatedEvent event = new ArmorStandManipulatedEvent(armorStand, getPlayer()); - Bukkit.getPluginManager().callEvent(event); // Bukkit handles the call out //TODO: Folia Refactor - if (event.isCancelled()) return; //do nothing if cancelled - - armorStand = attemptTarget(armorStand); - switch (eMode) { - case LEFTARM: - armorStand.setLeftArmPose(addEulerAngle(armorStand.getLeftArmPose())); - break; - case RIGHTARM: - armorStand.setRightArmPose(addEulerAngle(armorStand.getRightArmPose())); - break; - case BODY: - armorStand.setBodyPose(addEulerAngle(armorStand.getBodyPose())); - break; - case HEAD: - armorStand.setHeadPose(addEulerAngle(armorStand.getHeadPose())); - break; - case LEFTLEG: - armorStand.setLeftLegPose(addEulerAngle(armorStand.getLeftLegPose())); - break; - case RIGHTLEG: - armorStand.setRightLegPose(addEulerAngle(armorStand.getRightLegPose())); - break; - case PLACEMENT: - reverseMove(armorStand); - break; - case ROTATE: - reverseRotate(armorStand); - break; - default: - editArmorStand(armorStand); - } - } - - private void move(ArmorStand armorStand) { - if (!getPlayer().hasPermission("asedit.movement")) return; - - //Generate a new ArmorStandManipulationEvent and call it out. - ArmorStandManipulatedEvent event = new ArmorStandManipulatedEvent(armorStand, getPlayer()); - Bukkit.getPluginManager().callEvent(event); // Bukkit handles the call out //TODO: Folia Refactor - if (event.isCancelled()) return; //do nothing if cancelled - - Location loc = armorStand.getLocation(); - switch (axis) { - case X: - loc.add(movChange, 0, 0); - break; - case Y: - loc.add(0, movChange, 0); - break; - case Z: - loc.add(0, 0, movChange); - break; - } - Scheduler.teleport(armorStand, loc); - } - - private void reverseMove(ArmorStand armorStand) { - if (!getPlayer().hasPermission("asedit.movement")) return; - Location loc = armorStand.getLocation(); - switch (axis) { - case X: - loc.subtract(movChange, 0, 0); - break; - case Y: - loc.subtract(0, movChange, 0); - break; - case Z: - loc.subtract(0, 0, movChange); - break; - } - Scheduler.teleport(armorStand, loc); - } - - private void rotate(ArmorStand armorStand) { - if (!getPlayer().hasPermission("asedit.rotation")) return; - Location loc = armorStand.getLocation(); - float yaw = loc.getYaw(); - loc.setYaw((yaw + 180 + (float) degreeAngleChange) % 360 - 180); - Scheduler.teleport(armorStand, loc); - } - - private void reverseRotate(ArmorStand armorStand) { - if (!getPlayer().hasPermission("asedit.rotation")) return; - Location loc = armorStand.getLocation(); - float yaw = loc.getYaw(); - loc.setYaw((yaw + 180 - (float) degreeAngleChange) % 360 - 180); - Scheduler.teleport(armorStand, loc); - } - - private void copy(ArmorStand armorStand) { - if (getPlayer().hasPermission("asedit.copy")) { - copySlots.copyDataToSlot(armorStand); - sendMessage("copied", "" + (copySlots.currentSlot + 1)); - setMode(EditMode.PASTE); - }else{ - sendMessage("nopermoption", "warn", "copy"); - } - - } - - private void paste(ArmorStand armorStand) { - if (getPlayer().hasPermission("asedit.paste")) { - ArmorStandData data = copySlots.getDataToPaste(); - if (data == null) return; - armorStand.setHeadPose(data.headPos); - armorStand.setBodyPose(data.bodyPos); - armorStand.setLeftArmPose(data.leftArmPos); - armorStand.setRightArmPose(data.rightArmPos); - armorStand.setLeftLegPose(data.leftLegPos); - armorStand.setRightLegPose(data.rightLegPos); - armorStand.setSmall(data.size); - armorStand.setGravity(data.gravity); - armorStand.setBasePlate(data.basePlate); - armorStand.setArms(data.showArms); - armorStand.setVisible(data.visible); - - //Only Paste the Items on the stand if in Creative Mode - // - Do not run elsewhere for good fecking reason! - if (this.getPlayer().getGameMode() == GameMode.CREATIVE) { - armorStand.getEquipment().setHelmet(data.head); - armorStand.getEquipment().setChestplate(data.body); - armorStand.getEquipment().setLeggings(data.legs); - armorStand.getEquipment().setBoots(data.feetsies); - armorStand.getEquipment().setItemInMainHand(data.rightHand); - armorStand.getEquipment().setItemInOffHand(data.leftHand); - } - sendMessage("pasted", "" + (copySlots.currentSlot + 1)); - }else{ - sendMessage("nopermoption", "warn", "paste"); - } - } - - private void resetPosition(ArmorStand armorStand) { - if (getPlayer().hasPermission("asedit.reset")) { - armorStand.setHeadPose(new EulerAngle(0, 0, 0)); - armorStand.setBodyPose(new EulerAngle(0, 0, 0)); - armorStand.setLeftArmPose(new EulerAngle(0, 0, 0)); - armorStand.setRightArmPose(new EulerAngle(0, 0, 0)); - armorStand.setLeftLegPose(new EulerAngle(0, 0, 0)); - armorStand.setRightLegPose(new EulerAngle(0, 0, 0)); - } else{ - sendMessage("nopermoption", "warn", "reset"); - } - } - - private void toggleDisableSlots(ArmorStand armorStand) { - if (!getPlayer().hasPermission("asedit.disableSlots")){ - sendMessage("nopermoption", "warn", "disableslots"); - } else { - if (armorStand.hasEquipmentLock(EquipmentSlot.HAND, ArmorStand.LockType.REMOVING_OR_CHANGING)) { //Adds a lock to every slot or removes it - team = Scheduler.isFolia() ? null : plugin.scoreboard.getTeam(plugin.lockedTeam); - armorStandID = armorStand.getUniqueId(); - - for (final EquipmentSlot slot : EquipmentSlot.values()) { // UNLOCKED - armorStand.removeEquipmentLock(slot, ArmorStand.LockType.REMOVING_OR_CHANGING); - armorStand.removeEquipmentLock(slot, ArmorStand.LockType.ADDING); - } - getPlayer().playSound(getPlayer().getLocation(), Sound.ENTITY_ITEM_BREAK, SoundCategory.PLAYERS, 1.0f, 1.0f); - - if (team != null) { - team.removeEntry(armorStandID.toString()); - armorStand.addPotionEffect(new PotionEffect(PotionEffectType.GLOWING, 50, 1, false, false)); //300 Ticks = 15 seconds - } - - - } else { - for (final EquipmentSlot slot : EquipmentSlot.values()) { //LOCKED - armorStand.addEquipmentLock(slot, ArmorStand.LockType.REMOVING_OR_CHANGING); - armorStand.addEquipmentLock(slot, ArmorStand.LockType.ADDING); - } - getPlayer().playSound(getPlayer().getLocation(), Sound.ITEM_ARMOR_EQUIP_IRON, SoundCategory.PLAYERS, 1.0f, 1.0f); - if (team != null) { - team.addEntry(armorStandID.toString()); - armorStand.addPotionEffect(new PotionEffect(PotionEffectType.GLOWING, 50, 1, false, false)); //300 Ticks = 15 seconds - } - } - - sendMessage("disabledslots", null); - } - - } - - private void toggleInvulnerability(ArmorStand armorStand) { //See NewFeature-Request #256 for more info - if (getPlayer().hasPermission("asedit.toggleInvulnerability")) { - armorStand.setInvulnerable(!armorStand.isInvulnerable()); - sendMessage("toggleinvulnerability", String.valueOf(armorStand.isInvulnerable())); - } else { - sendMessage("nopermoption","warn", "vulnerability"); - } - } - - - private void toggleGravity(ArmorStand armorStand) { - if (getPlayer().hasPermission("asedit.togglegravity")){ - armorStand.setGravity(!armorStand.hasGravity()); - sendMessage("setgravity", String.valueOf(armorStand.hasGravity()));//Fix for Wolfst0rm/ArmorStandEditor-Issues#6: Translation of On/Off Keys are broken - } else{ - sendMessage("nopermoption","warn", "gravity"); - } - - - - } - - void togglePlate(ArmorStand armorStand) { - if(getPlayer().hasPermission("asedit.togglebaseplate")){ - armorStand.setBasePlate(!armorStand.hasBasePlate()); - } else{ - sendMessage("nopermoption", "warn", "baseplate"); - } - - } - - void toggleGlowing(ArmorStand armorStand){ - if(getPlayer().hasPermission("asedit.togglearmorstandglow")){ - //Will only make it glow white - Not something we can do like with Locking. Do not request this! - //Otherwise, this simple function becomes a mess to maintain. As you would need a Team generated with each - //Color and I ain't going to impose that on servers. - armorStand.setGlowing(!armorStand.isGlowing()); - } else{ - sendMessage("nopermoption", "warn", "armorstandglow"); - } - } - - void toggleArms(ArmorStand armorStand) { - if(getPlayer().hasPermission("asedit.togglearms")){ - armorStand.setArms(!armorStand.hasArms()); - }else{ - sendMessage("nopermoption", "warn", "showarms"); - } - } - - void toggleVisible(ArmorStand armorStand) { - if(getPlayer().hasPermission("asedit.togglearmorstandvisibility") || plugin.getArmorStandVisibility()){ - armorStand.setVisible(!armorStand.isVisible()); - } else{ //Throw No Permission Message - sendMessage("nopermoption", "warn", "armorstandvisibility"); - } - } - - void toggleItemFrameVisible(ItemFrame itemFrame) { - if (getPlayer().hasPermission("asedit.toggleitemframevisibility") || plugin.invisibleItemFrames) { //Option to use perms or Config - itemFrame.setVisible(!itemFrame.isVisible()); - }else { - sendMessage("nopermoption", "warn", "itemframevisibility"); - } - } - - void toggleSize(ArmorStand armorStand) { - if (getPlayer().hasPermission("asedit.togglesize")) { - armorStand.setSmall(!armorStand.isSmall()); - } else { - sendMessage("nopermoption", "warn", "size"); - } - } - - void cycleAxis(int i) { - int index = axis.ordinal(); - index += i; - index = index % Axis.values().length; - while (index < 0) { - index += Axis.values().length; - } - setAxis(Axis.values()[index]); - } - - private EulerAngle addEulerAngle(EulerAngle angle) { - switch (axis) { - case X: - angle = angle.setX(Util.addAngle(angle.getX(), eulerAngleChange)); - break; - case Y: - angle = angle.setY(Util.addAngle(angle.getY(), eulerAngleChange)); - break; - case Z: - angle = angle.setZ(Util.addAngle(angle.getZ(), eulerAngleChange)); - break; - default: - break; - } - return angle; - } - - private EulerAngle subEulerAngle(EulerAngle angle) { - switch (axis) { - case X: - angle = angle.setX(Util.subAngle(angle.getX(), eulerAngleChange)); - break; - case Y: - angle = angle.setY(Util.subAngle(angle.getY(), eulerAngleChange)); - break; - case Z: - angle = angle.setZ(Util.subAngle(angle.getZ(), eulerAngleChange)); - break; - default: - break; - } - return angle; - } - - - public void setTarget(ArrayList armorStands) { - if (armorStands == null || armorStands.isEmpty()) { - target = null; - targetList = null; - sendMessage("notarget", "armorstand"); - } else { - if (targetList == null) { - targetList = armorStands; - targetIndex = 0; - sendMessage("target", null); - } else { - boolean same = targetList.size() == armorStands.size(); - if (same) for (ArmorStand as : armorStands) { - same = targetList.contains(as); - if (!same) break; - } - - if (same) { - targetIndex = ++targetIndex % targetList.size(); - } else { - targetList = armorStands; - targetIndex = 0; - sendMessage("target", null); - } - } - - //API: ArmorStandTargetedEvent - ArmorStandTargetedEvent e = new ArmorStandTargetedEvent(targetList.get(targetIndex), getPlayer()); - Bukkit.getPluginManager().callEvent(e); //TODO: Folia Refactor - if (e.isCancelled()) return; - - target = targetList.get(targetIndex); - highlight(target); //NOTE: If Targeted and Locked, it displays the TEAM Color Glow: RED - // Otherwise, its unlocked and will display WHITE as its not in a team by default - - } - } - - - public void setFrameTarget(ArrayList itemFrames) { - if (itemFrames == null || itemFrames.isEmpty()) { - frameTarget = null; - frameTargetList = null; - sendMessage("notarget", "itemframe"); - } else { - - if (frameTargetList == null) { - frameTargetList = itemFrames; - frameTargetIndex = 0; - sendMessage("frametarget", null); - } else { - boolean same = frameTargetList.size() == itemFrames.size(); - if (same) for (final ItemFrame itemf : itemFrames) { - same = frameTargetList.contains(itemf); - if (!same) break; - } - - if (same) { - frameTargetIndex = ++frameTargetIndex % frameTargetList.size(); - } else { - frameTargetList = itemFrames; - frameTargetIndex = 0; - sendMessage("frametarget", null); - } - - //API: ItemFrameTargetedEvent - ItemFrameTargetedEvent e = new ItemFrameTargetedEvent(frameTargetList.get(frameTargetIndex), getPlayer()); - Bukkit.getPluginManager().callEvent(e); //TODO: Folia Refactor - if (e.isCancelled()) return; - - frameTarget = frameTargetList.get(frameTargetIndex); - } - } - } - - - - ArmorStand attemptTarget(ArmorStand armorStand) { - if (target == null - || !target.isValid() - || target.getWorld() != getPlayer().getWorld() - || target.getLocation().distanceSquared(getPlayer().getLocation()) > 100) - return armorStand; - armorStand = target; - return armorStand; - } - - void sendMessage(String path, String format, String option) { - String message = plugin.getLang().getMessage(path, format, option); - if (plugin.sendToActionBar) { - if (ArmorStandEditorPlugin.instance().getHasPaper() || ArmorStandEditorPlugin.instance().getHasSpigot()) { //Paper and Spigot having the same Interaction for sendToActionBar - plugin.getServer().getPlayer(getUUID()).spigot().sendMessage(ChatMessageType.ACTION_BAR, new TextComponent(message)); - } else { - String rawText = plugin.getLang().getRawMessage(path, format, option); - String command = "title %s actionbar %s".formatted(plugin.getServer().getPlayer(getUUID()).getName(), rawText); - Bukkit.dispatchCommand(Bukkit.getConsoleSender(), command); - } - } else { - plugin.getServer().getPlayer(getUUID()).sendMessage(message); - } - } - - void sendMessage(String path, String option) { - sendMessage(path, "info", option); - } - - private void highlight(ArmorStand armorStand) { - armorStand.removePotionEffect(PotionEffectType.GLOWING); - armorStand.addPotionEffect(new PotionEffect(PotionEffectType.GLOWING, 50, 1, false, false)); //300 Ticks = 15 seconds - } - - public PlayerEditorManager getManager() { - return plugin.editorManager; - } - - public Player getPlayer() { - return plugin.getServer().getPlayer(getUUID()); - } - - public UUID getUUID() { - return uuid; - } - - public void openMenu() { - if (!isMenuCancelled()) { - Scheduler.runTaskLater(plugin, new OpenMenuTask(), 1); - } - } - - public void cancelOpenMenu() { - lastCancelled = getManager().getTime(); - } - - boolean isMenuCancelled() { - return getManager().getTime() - lastCancelled < 2; - } - - private class OpenMenuTask implements Runnable { - - @Override - public void run() { - if (isMenuCancelled()) return; - - //API: PlayerOpenMenuEvent - PlayerOpenMenuEvent event = new PlayerOpenMenuEvent(getPlayer()); - Bukkit.getPluginManager().callEvent(event); //TODO: Folia Refactor - if (event.isCancelled()) return; - - chestMenu.openMenu(); - } - } -} diff --git a/src/main/java/io/github/rypofalem/armorstandeditor/PlayerEditorManager.java b/src/main/java/io/github/rypofalem/armorstandeditor/PlayerEditorManager.java deleted file mode 100644 index aa341a88..00000000 --- a/src/main/java/io/github/rypofalem/armorstandeditor/PlayerEditorManager.java +++ /dev/null @@ -1,493 +0,0 @@ -/* - * ArmorStandEditor: Bukkit plugin to allow editing armor stand attributes - * Copyright (C) 2016-2023 RypoFalem - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -package io.github.rypofalem.armorstandeditor; - -import com.google.common.collect.ImmutableList; - -import io.github.rypofalem.armorstandeditor.api.ArmorStandRenameEvent; -import io.github.rypofalem.armorstandeditor.api.ItemFrameGlowEvent; -import io.github.rypofalem.armorstandeditor.menu.ASEHolder; -import io.github.rypofalem.armorstandeditor.protections.*; - -import org.bukkit.*; -import org.bukkit.block.Block; -import org.bukkit.block.BlockFace; -import org.bukkit.entity.*; -import org.bukkit.event.*; -import org.bukkit.event.block.Action; -import org.bukkit.event.entity.EntityDamageByEntityEvent; -import org.bukkit.event.inventory.InventoryClickEvent; -import org.bukkit.event.inventory.InventoryCloseEvent; -import org.bukkit.event.player.*; -import org.bukkit.inventory.EquipmentSlot; -import org.bukkit.inventory.ItemStack; -import org.bukkit.persistence.PersistentDataType; -import org.bukkit.util.Vector; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.UUID; - -//Manages PlayerEditors and Player Events related to editing armorstands -public class PlayerEditorManager implements Listener { - private ArmorStandEditorPlugin plugin; - private HashMap players; - private ASEHolder menuHolder = new ASEHolder(); //Inventory holder that owns the main ase menu inventories for the plugin - private ASEHolder equipmentHolder = new ASEHolder(); //Inventory holder that owns the equipment menu - private ASEHolder presetHolder = new ASEHolder(); //Inventory Holder that owns the PresetArmorStand Post Menu - double coarseAdj; - double fineAdj; - double coarseMov; - double fineMov; - private boolean ignoreNextInteract = false; - private TickCounter counter; - private ArrayList as = null; - private ArrayList itemF = null; - private Integer noSize = 0; - - // Instantiate protections used to determine whether a player may edit an armor stand or item frame - //NOTE: GriefPreventionProtection is Depreciated as of v1.19.3-40 - private final List protections = ImmutableList.of( - new GriefDefenderProtection(), - new GriefPreventionProtection(), - new LandsProtection(), - new PlotSquaredProtection(), - new SkyblockProtection(), - new TownyProtection(), - new WorldGuardProtection(), - new BentoBoxProtection()); - - PlayerEditorManager(ArmorStandEditorPlugin plugin) { - this.plugin = plugin; - players = new HashMap<>(); - coarseAdj = Util.FULL_CIRCLE / plugin.coarseRot; - fineAdj = Util.FULL_CIRCLE / plugin.fineRot; - coarseMov = 1; - fineMov = .03125; // 1/32 - counter = new TickCounter(); - Scheduler.runTaskTimer(plugin, counter, 1, 1); - } - - @EventHandler(priority = EventPriority.LOWEST) - void onArmorStandDamage(EntityDamageByEntityEvent event) { - if (!(event.getDamager() instanceof Player)) return; - Player player = (Player) event.getDamager(); - if (!plugin.isEditTool(player.getInventory().getItemInMainHand())) return; - if (!((event.getEntity() instanceof ArmorStand) || event.getEntity() instanceof ItemFrame)) { - event.setCancelled(true); - getPlayerEditor(player.getUniqueId()).openMenu(); - return; - } - if (event.getEntity() instanceof ArmorStand) { - ArmorStand as = (ArmorStand) event.getEntity(); - getPlayerEditor(player.getUniqueId()).cancelOpenMenu(); - event.setCancelled(true); - if (canEdit(player, as)) - applyLeftTool(player, as); - } else if (event.getEntity() instanceof ItemFrame) { - ItemFrame itemf = (ItemFrame) event.getEntity(); - getPlayerEditor(player.getUniqueId()).cancelOpenMenu(); - event.setCancelled(true); - if (canEdit(player, itemf)) applyLeftTool(player, itemf); - } - } - - @EventHandler(priority = EventPriority.LOWEST) - void onArmorStandInteract(PlayerInteractAtEntityEvent event) { - if (ignoreNextInteract) return; - if (event.getHand() != EquipmentSlot.HAND) return; - Player player = event.getPlayer(); - if (!((event.getRightClicked() instanceof ArmorStand) || event.getRightClicked() instanceof ItemFrame)) return; - - if (event.getRightClicked() instanceof ArmorStand) { - ArmorStand as = (ArmorStand) event.getRightClicked(); - - if (!canEdit(player, as)) return; - if (plugin.isEditTool(player.getInventory().getItemInMainHand())) { - getPlayerEditor(player.getUniqueId()).cancelOpenMenu(); - event.setCancelled(true); - applyRightTool(player, as); - return; - } - - - //Attempt rename - if (player.getInventory().getItemInMainHand().getType() == Material.NAME_TAG && player.hasPermission("asedit.rename")) { - ItemStack nameTag = player.getInventory().getItemInMainHand(); - String name; - if (nameTag.getItemMeta() != null && nameTag.getItemMeta().hasDisplayName()) { - name = nameTag.getItemMeta().getDisplayName().replace('&', ChatColor.COLOR_CHAR); - } else { - name = null; - } - - //API: ArmorStandRenameEvent - ArmorStandRenameEvent e = new ArmorStandRenameEvent(as, player, name); - Bukkit.getPluginManager().callEvent(e); - if (e.isCancelled()) return; - - if (name == null) { - as.setCustomName(null); - as.setCustomNameVisible(false); - event.setCancelled(true); - } else if (!name.equals("")) { // nametag is not blank - event.setCancelled(true); - - if ((player.getGameMode() != GameMode.CREATIVE)) { - if (nameTag.getAmount() > 1) { - nameTag.setAmount(nameTag.getAmount() - 1); - } else { - nameTag = new ItemStack(Material.AIR); - } - player.getInventory().setItemInMainHand(nameTag); - } - - //minecraft will set the name after this event even if the event is cancelled. - //change it 1 tick later to apply formatting without it being overwritten - Scheduler.runTaskLater(plugin, () -> { - as.setCustomName(name); - as.setCustomNameVisible(true); - }, 1); - } - } - } else if (event.getRightClicked() instanceof ItemFrame) { - ItemFrame itemFrame = (ItemFrame) event.getRightClicked(); - - if (!canEdit(player, itemFrame)) return; - if (plugin.isEditTool(player.getInventory().getItemInMainHand())) { - getPlayerEditor(player.getUniqueId()).cancelOpenMenu(); - if (!itemFrame.getItem().getType().equals(Material.AIR)) { - event.setCancelled(true); - } - applyRightTool(player, itemFrame); - return; - } - - if (player.getInventory().getItemInMainHand().getType().equals(Material.GLOW_INK_SAC) //attempt glowing - && player.hasPermission("asedit.basic") - && plugin.glowItemFrames && player.isSneaking()) { - - ItemFrameGlowEvent e = new ItemFrameGlowEvent(itemFrame, player); - Bukkit.getPluginManager().callEvent(e); - if (e.isCancelled()) return; - - ItemStack glowSacs = player.getInventory().getItemInMainHand(); - ItemStack contents = null; - Rotation rotation = null; - if (itemFrame.getItem().getType() != Material.AIR) { - contents = itemFrame.getItem(); //save item - rotation = itemFrame.getRotation(); // save item rotation - } - Location itemFrameLocation = itemFrame.getLocation(); - BlockFace facing = itemFrame.getFacing(); - - if (player.getGameMode() != GameMode.CREATIVE) { - if (glowSacs.getAmount() > 1) { - glowSacs.setAmount(glowSacs.getAmount() - 1); - } else glowSacs = new ItemStack(Material.AIR); - } - - itemFrame.remove(); - GlowItemFrame glowFrame = (GlowItemFrame) player.getWorld().spawnEntity(itemFrameLocation, EntityType.GLOW_ITEM_FRAME); - glowFrame.setFacingDirection(facing); - if (contents != null) { - glowFrame.setItem(contents); - glowFrame.setRotation(rotation); - } - - } - } - } - - @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) - void onArmorStandBreak(EntityDamageByEntityEvent event) { // Fixes issue #309 - if (!(event.getDamager() instanceof Player)) return; // If the damager is not a player, ignore. - if (!(event.getEntity() instanceof ArmorStand)) return; // If the damaged entity is not an ArmorStand, ignore. - - if (event.getEntity() instanceof ArmorStand entityAS) { - // Check if the ArmorStand is invulnerable and if the damager is a player. - if (entityAS.isInvulnerable() && event.getDamager() instanceof Player p) { - // Check if the player is in Creative mode. - if (p.getGameMode() == GameMode.CREATIVE) { - // If the player is in Creative mode and the ArmorStand is invulnerable, - // cancel the event to prevent breaking the ArmorStand. - p.sendMessage(plugin.getLang().getMessage("unabledestroycreative")); - event.setCancelled(true); // Cancel the event to prevent ArmorStand destruction. - } - } - } - - if(event.getEntity() instanceof ArmorStand entityAS && entityAS.isDead()){ - //TODO: Find a more permanent fix for "Once you destroy that armor stand, the armor stand will keep it's name and colour given by the name tag." THIS IS A TEMP SOLUTION FOR NOW. - event.getEntity().setCustomName(null); - event.getEntity().setCustomNameVisible(false); - event.setCancelled(false); - } - } - - @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) - public void onSwitchHands(PlayerSwapHandItemsEvent event) { - if (!plugin.isEditTool(event.getOffHandItem())) return; //event assumes they are already switched - event.setCancelled(true); - Player player = event.getPlayer(); - - as = getTargets(player); //Get All ArmorStand closest to player - itemF = getFrameTargets(player); //Get ItemFrame Closest to Player - - - // Check for null and empty lists - if (as != null && itemF != null && !as.isEmpty() && !itemF.isEmpty()) { - getPlayerEditor(player.getUniqueId()).sendMessage("doubletarget", "warn"); - } else if (as != null && !as.isEmpty()) { - getPlayerEditor(player.getUniqueId()).setTarget(as); - } else if (itemF != null && !itemF.isEmpty()) { - getPlayerEditor(player.getUniqueId()).setFrameTarget(itemF); - } else { - getPlayerEditor(player.getUniqueId()).sendMessage("nodoubletarget","warn"); - } - } - - private ArrayList getTargets(Player player) { - Location eyeLaser = player.getEyeLocation(); - Vector direction = player.getLocation().getDirection(); - ArrayList armorStands = new ArrayList<>(); - - double STEPSIZE = .5; - Vector STEP = direction.multiply(STEPSIZE); - double RANGE = 10; - double LASERRADIUS = .3; - List nearbyEntities = player.getNearbyEntities(RANGE, RANGE, RANGE); - if (nearbyEntities.isEmpty()) return null; - - for (double i = 0; i < RANGE; i += STEPSIZE) { - List nearby = (List) player.getWorld().getNearbyEntities(eyeLaser, LASERRADIUS, LASERRADIUS, LASERRADIUS); - if (!nearby.isEmpty()) { - boolean endLaser = false; - for (Entity e : nearby) { - if (e instanceof ArmorStand stand) { - armorStands.add(stand); - endLaser = true; - } - } - - if (endLaser) break; - } - if (eyeLaser.getBlock().getType().isSolid()) break; - eyeLaser.add(STEP); - } - return armorStands; - } - - private ArrayList getFrameTargets(Player player) { - Location eyeLaser = player.getEyeLocation(); - Vector direction = player.getLocation().getDirection(); - ArrayList itemFrames = new ArrayList<>(); - - double STEPSIZE = .5; - Vector STEP = direction.multiply(STEPSIZE); - double RANGE = 10; - double LASERRADIUS = .3; - List nearbyEntities = player.getNearbyEntities(RANGE, RANGE, RANGE); - if (nearbyEntities.isEmpty()) return null; - - for (double i = 0; i < RANGE; i += STEPSIZE) { - List nearby = (List) player.getWorld().getNearbyEntities(eyeLaser, LASERRADIUS, LASERRADIUS, LASERRADIUS); - if (!nearby.isEmpty()) { - boolean endLaser = false; - for (Entity e : nearby) { - if (e instanceof ItemFrame frame) { - itemFrames.add(frame); - endLaser = true; - } - } - - if (endLaser) break; - } - if (eyeLaser.getBlock().getType().isSolid()) break; - eyeLaser.add(STEP); - } - - return itemFrames; - } - - - boolean canEdit(Player player, Entity entity) { - //Get the Entity being checked for editing - Block block = entity.getLocation().getBlock(); - - // Check if all protections allow this edit, if one fails, don't allow edit - return protections.stream().allMatch(protection -> protection.checkPermission(block, player)); - } - - void applyLeftTool(Player player, ArmorStand as) { - getPlayerEditor(player.getUniqueId()).cancelOpenMenu(); - getPlayerEditor(player.getUniqueId()).editArmorStand(as); - } - - void applyLeftTool(Player player, ItemFrame itemf) { - getPlayerEditor(player.getUniqueId()).cancelOpenMenu(); - getPlayerEditor(player.getUniqueId()).editItemFrame(itemf); - } - - void applyRightTool(Player player, ItemFrame itemf) { - getPlayerEditor(player.getUniqueId()).cancelOpenMenu(); - getPlayerEditor(player.getUniqueId()).editItemFrame(itemf); - } - - void applyRightTool(Player player, ArmorStand as) { - getPlayerEditor(player.getUniqueId()).cancelOpenMenu(); - getPlayerEditor(player.getUniqueId()).reverseEditArmorStand(as); - } - - //Unused? - @EventHandler(priority = EventPriority.LOWEST) - void onRightClickTool(PlayerInteractEvent e) { - if (!(e.getAction() == Action.LEFT_CLICK_AIR - || e.getAction() == Action.RIGHT_CLICK_AIR - || e.getAction() == Action.LEFT_CLICK_BLOCK - || e.getAction() == Action.RIGHT_CLICK_BLOCK)) return; - Player player = e.getPlayer(); - if (!plugin.isEditTool(player.getInventory().getItemInMainHand())) return; - if (plugin.requireSneaking && !player.isSneaking()) return; - if (!player.hasPermission("asedit.basic")) return; - if (plugin.enablePerWorld && (!plugin.allowedWorldList.contains(player.getWorld().getName()))) { - //Implementation for Per World ASE - getPlayerEditor(player.getUniqueId()).sendMessage("notincorrectworld", "warn"); - e.setCancelled(true); - return; - } - e.setCancelled(true); - getPlayerEditor(player.getUniqueId()).openMenu(); - } - - @EventHandler(priority = EventPriority.NORMAL) - void onScrollNCrouch(PlayerItemHeldEvent e) { - Player player = e.getPlayer(); - if (!player.isSneaking()) return; - if (!plugin.isEditTool(player.getInventory().getItem(e.getPreviousSlot()))) return; - - e.setCancelled(true); - if (e.getNewSlot() == e.getPreviousSlot() + 1 || (e.getNewSlot() == 0 && e.getPreviousSlot() == 8)) { - getPlayerEditor(player.getUniqueId()).cycleAxis(1); - } else if (e.getNewSlot() == e.getPreviousSlot() - 1 || (e.getNewSlot() == 8 && e.getPreviousSlot() == 0)) { - getPlayerEditor(player.getUniqueId()).cycleAxis(-1); - } - } - - @EventHandler(priority = EventPriority.LOWEST) - void onPlayerMenuSelect(InventoryClickEvent e) { - if (e.getInventory().getHolder() == null) return; - if (!(e.getInventory().getHolder() instanceof ASEHolder)) return; - if (e.getInventory().getHolder() == menuHolder) { - e.setCancelled(true); - ItemStack item = e.getCurrentItem(); - if (item != null && item.hasItemMeta()) { - Player player = (Player) e.getWhoClicked(); - String command = item.getItemMeta().getPersistentDataContainer().get(plugin.getIconKey(), PersistentDataType.STRING); - if (command != null) { - player.performCommand(command); - return; - } - } - } - if (e.getInventory().getHolder() == equipmentHolder) { - ItemStack item = e.getCurrentItem(); - if (item == null) return; - if (item.getItemMeta() == null) return; - if (item.getItemMeta().getPersistentDataContainer().has(plugin.getIconKey(), PersistentDataType.STRING)) { - e.setCancelled(true); - } - } - - if (e.getInventory().getHolder() == presetHolder){ - e.setCancelled(true); - ItemStack item = e.getCurrentItem(); - if(item != null && item.hasItemMeta()){ - Player player = (Player) e.getWhoClicked(); - String itemName = item.getItemMeta().getDisplayName(); - PlayerEditor pe = players.get(player.getUniqueId()); - pe.presetPoseMenu.handlePresetPose(itemName, player); - } - } - } - - - - @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) - void onPlayerMenuClose(InventoryCloseEvent e) { - if (e.getInventory().getHolder() == null) return; - if (!(e.getInventory().getHolder() instanceof ASEHolder)) return; - if (e.getInventory().getHolder() == equipmentHolder) { - PlayerEditor pe = players.get(e.getPlayer().getUniqueId()); - pe.equipMenu.equipArmorstand(); - } - } - - @EventHandler(priority = EventPriority.MONITOR) - void onPlayerLogOut(PlayerQuitEvent e) { - removePlayerEditor(e.getPlayer().getUniqueId()); - } - - public PlayerEditor getPlayerEditor(UUID uuid) { - return players.containsKey(uuid) ? players.get(uuid) : addPlayerEditor(uuid); - } - - PlayerEditor addPlayerEditor(UUID uuid) { - PlayerEditor pe = new PlayerEditor(uuid, plugin); - players.put(uuid, pe); - return pe; - } - - private void removePlayerEditor(UUID uuid) { - players.remove(uuid); - } - - public ASEHolder getMenuHolder() { - return menuHolder; - } - - public ASEHolder getEquipmentHolder() { - return equipmentHolder; - } - - public ASEHolder getPresetHolder() { - return presetHolder; - } - - long getTime() { - return counter.ticks; - } - - - - class TickCounter implements Runnable { - long ticks = 0; //I am optimistic - - @Override - public void run() { - ticks++; - } - - public long getTime() { - return ticks; - } - } -} diff --git a/src/main/java/io/github/rypofalem/armorstandeditor/Scheduler.java b/src/main/java/io/github/rypofalem/armorstandeditor/Scheduler.java deleted file mode 100644 index b2014351..00000000 --- a/src/main/java/io/github/rypofalem/armorstandeditor/Scheduler.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * ArmorStandEditor: Bukkit plugin to allow editing armor stand attributes - * Copyright (C) 2016-2023 RypoFalem - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package io.github.rypofalem.armorstandeditor; - -import org.bukkit.Bukkit; -import org.bukkit.Location; -import org.bukkit.entity.Entity; -import org.bukkit.plugin.Plugin; - -import java.util.function.Consumer; - -public class Scheduler { - - private static Boolean IS_FOLIA = null; - private static Object GLOBAL_REGION_SCHEDULER = null; - - public static T callMethod(Class clazz, Object object, String methodName, Class[] parameterTypes, Object... args) { - try { - return (T) clazz.getDeclaredMethod(methodName, parameterTypes).invoke(object, args); - } catch (Throwable t) { - throw new IllegalStateException(t); - } - } - - public static T callMethod(Object object, String methodName, Class[] parameterTypes, Object... args) { - return callMethod(object.getClass(), object, methodName, parameterTypes, args); - } - - public static T callMethod(Class clazz, String methodName) { - return callMethod(clazz, null, methodName, new Class[]{}); - } - - private static boolean methodExist(Class clazz, String methodName, Class... parameterTypes) { - try { - clazz.getDeclaredMethod(methodName, parameterTypes); - return true; - } catch (Throwable ignored) { - } - return false; - } - - public static Boolean isFolia() { - try { - Class.forName("io.papermc.paper.threadedregions.ThreadedRegionizer"); - } - catch (Exception e) { - return false; - } - return true; - } - - public static Object getGlobalRegionScheduler() { - if (GLOBAL_REGION_SCHEDULER == null) { - GLOBAL_REGION_SCHEDULER = callMethod(Bukkit.class, "getGlobalRegionScheduler"); - } - return GLOBAL_REGION_SCHEDULER; - } - - public static void runTask(Plugin plugin, Runnable runnable) { - if (isFolia()) { - Object globalRegionScheduler = getGlobalRegionScheduler(); - callMethod(globalRegionScheduler, "run", new Class[]{Plugin.class, Consumer.class}, plugin, (Consumer) (task) -> runnable.run()); - return; - } - Bukkit.getScheduler().runTask(plugin, runnable); - } - - public static void runTaskTimer(Plugin plugin, Runnable runnable, long initialDelayTicks, long periodTicks) { - if (isFolia()) { - Object globalRegionScheduler = getGlobalRegionScheduler(); - callMethod(globalRegionScheduler, "runAtFixedRate", new Class[]{Plugin.class, Consumer.class, long.class, long.class}, - plugin, (Consumer) (task) -> runnable.run(), initialDelayTicks, periodTicks); - return; - } - Bukkit.getScheduler().runTaskTimerAsynchronously(plugin, runnable, initialDelayTicks, periodTicks); - } - - public static void runTaskLater(Plugin plugin, Runnable runnable, long delayedTicks) { - if (isFolia()) { - Object globalRegionScheduler = getGlobalRegionScheduler(); - callMethod(globalRegionScheduler, "runDelayed", new Class[]{Plugin.class, Consumer.class, long.class}, - plugin, (Consumer) (task) -> runnable.run(), delayedTicks); - return; - } - Bukkit.getScheduler().runTaskLater(plugin, runnable, delayedTicks); - } - - public static void teleport(Entity entity, Location location) { - if (isFolia()) callMethod(Entity.class, entity, "teleportAsync", new Class[]{Location.class}, location); - else entity.teleport(location); - } -} diff --git a/src/main/java/io/github/rypofalem/armorstandeditor/Util.java b/src/main/java/io/github/rypofalem/armorstandeditor/Util.java deleted file mode 100644 index 3c77e847..00000000 --- a/src/main/java/io/github/rypofalem/armorstandeditor/Util.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * ArmorStandEditor: Bukkit plugin to allow editing armor stand attributes - * Copyright (C) 2016-2023 RypoFalem - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -package io.github.rypofalem.armorstandeditor; - -public abstract class Util { - - public static final double FULL_CIRCLE = Math.PI * 2; - - public static > String getEnumList(Class enumType) { - return getEnumList(enumType, " | "); - } - - public static > String getEnumList(Class enumType, String delimiter) { - StringBuilder list = new StringBuilder(); - boolean put = false; - for (Enum e : enumType.getEnumConstants()) { - list.append(e.toString()).append(delimiter); - put = true; - } - if (put) list = new StringBuilder(list.substring(0, list.length() - delimiter.length())); - return list.toString(); - } - - public static double addAngle(double current, double angleChange) { - current += angleChange; - current = fixAngle(current, angleChange); - return current; - } - - public static double subAngle(double current, double angleChange) { - current -= angleChange; - current = fixAngle(current, angleChange); - return current; - } - - //clamps angle to 0 if it exceeds 2PI rad (360 degrees), is closer to 0 than angleChange value, or is closer to 2PI rad than 2PI rad - angleChange value. - private static double fixAngle(double angle, double angleChange) { - if (angle > FULL_CIRCLE) { - return 0; - } - - if (angle > 0 && angle < angleChange && angle < angleChange / 2) { - return 0; - } - - if (angle > FULL_CIRCLE - angle && angle > FULL_CIRCLE - (angleChange / 2)) { - return 0; - } - - return angle; - } -} diff --git a/src/main/java/io/github/rypofalem/armorstandeditor/api/ArmorStandEvent.java b/src/main/java/io/github/rypofalem/armorstandeditor/api/ArmorStandEvent.java deleted file mode 100644 index e82445c1..00000000 --- a/src/main/java/io/github/rypofalem/armorstandeditor/api/ArmorStandEvent.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * ArmorStandEditor: Bukkit plugin to allow editing armor stand attributes - * Copyright (C) 2016-2023 RypoFalem - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -package io.github.rypofalem.armorstandeditor.api; - -import lombok.Getter; - -import org.bukkit.entity.ArmorStand; -import org.bukkit.event.Event; - -public abstract class ArmorStandEvent extends Event { - - @Getter - protected final ArmorStand armorStand; - - public ArmorStandEvent(ArmorStand armorStand) { - this.armorStand = armorStand; - } - -} \ No newline at end of file diff --git a/src/main/java/io/github/rypofalem/armorstandeditor/api/ArmorStandManipulatedEvent.java b/src/main/java/io/github/rypofalem/armorstandeditor/api/ArmorStandManipulatedEvent.java deleted file mode 100644 index 9df80d7a..00000000 --- a/src/main/java/io/github/rypofalem/armorstandeditor/api/ArmorStandManipulatedEvent.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * ArmorStandEditor: Bukkit plugin to allow editing armor stand attributes - * Copyright (C) 2016-2023 RypoFalem - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package io.github.rypofalem.armorstandeditor.api; - -import lombok.Getter; -import lombok.Setter; - -import org.bukkit.entity.ArmorStand; -import org.bukkit.entity.Player; -import org.bukkit.event.Cancellable; -import org.bukkit.event.HandlerList; - -public class ArmorStandManipulatedEvent extends ArmorStandEvent implements Cancellable { - - @Getter - @Setter - private boolean cancelled = false; - - @Getter - protected final Player player; - - public ArmorStandManipulatedEvent(ArmorStand armorStand, Player player) { - super(armorStand); - this.player = player; - } - - /* Generated for Bukkit */ - private static final HandlerList handlers = new HandlerList(); - - public static HandlerList getHandlerList() { - return (handlers); - } - - @Override - public HandlerList getHandlers() { - return (handlers); - } -} diff --git a/src/main/java/io/github/rypofalem/armorstandeditor/api/ArmorStandRenameEvent.java b/src/main/java/io/github/rypofalem/armorstandeditor/api/ArmorStandRenameEvent.java deleted file mode 100644 index 5b243872..00000000 --- a/src/main/java/io/github/rypofalem/armorstandeditor/api/ArmorStandRenameEvent.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * ArmorStandEditor: Bukkit plugin to allow editing armor stand attributes - * Copyright (C) 2016-2023 RypoFalem - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package io.github.rypofalem.armorstandeditor.api; - -import lombok.Getter; -import lombok.Setter; - -import org.bukkit.entity.ArmorStand; -import org.bukkit.entity.Player; -import org.bukkit.event.Cancellable; -import org.bukkit.event.HandlerList; - -public class ArmorStandRenameEvent extends ArmorStandEvent implements Cancellable { - - @Getter - @Setter - private boolean cancelled = false; - @Getter - @Setter - protected String name; - - @Getter - protected final Player player; - - public ArmorStandRenameEvent(ArmorStand armorStand, Player player, String name) { - super(armorStand); - this.player = player; - this.name = name; - } - - /* Generated for Bukkit */ - private static final HandlerList handlers = new HandlerList(); - - public static HandlerList getHandlerList() { - return (handlers); - } - - @Override - public HandlerList getHandlers() { - return (handlers); - } - -} diff --git a/src/main/java/io/github/rypofalem/armorstandeditor/api/ArmorStandTargetedEvent.java b/src/main/java/io/github/rypofalem/armorstandeditor/api/ArmorStandTargetedEvent.java deleted file mode 100644 index 196a039e..00000000 --- a/src/main/java/io/github/rypofalem/armorstandeditor/api/ArmorStandTargetedEvent.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * ArmorStandEditor: Bukkit plugin to allow editing armor stand attributes - * Copyright (C) 2016-2023 RypoFalem - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -package io.github.rypofalem.armorstandeditor.api; - -import lombok.Getter; -import lombok.Setter; - -import org.bukkit.entity.ArmorStand; -import org.bukkit.entity.Player; -import org.bukkit.event.Cancellable; -import org.bukkit.event.HandlerList; - -public class ArmorStandTargetedEvent extends ArmorStandEvent implements Cancellable { - @Getter - @Setter - private boolean cancelled = false; - - @Getter - protected final Player player; - - public ArmorStandTargetedEvent(ArmorStand armorStand, Player player) { - super(armorStand); - this.player = player; - } - - /* Generated for Bukkit */ - private static final HandlerList handlers = new HandlerList(); - - public static HandlerList getHandlerList() { - return (handlers); - } - - @Override - public HandlerList getHandlers() { - return (handlers); - } -} \ No newline at end of file diff --git a/src/main/java/io/github/rypofalem/armorstandeditor/api/ItemFrameEvent.java b/src/main/java/io/github/rypofalem/armorstandeditor/api/ItemFrameEvent.java deleted file mode 100644 index d6358613..00000000 --- a/src/main/java/io/github/rypofalem/armorstandeditor/api/ItemFrameEvent.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * ArmorStandEditor: Bukkit plugin to allow editing armor stand attributes - * Copyright (C) 2016-2023 RypoFalem - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -package io.github.rypofalem.armorstandeditor.api; - -import lombok.Getter; - -import org.bukkit.entity.ItemFrame; -import org.bukkit.event.Event; - -public abstract class ItemFrameEvent extends Event { - - @Getter - protected final ItemFrame itemFrame; - - public ItemFrameEvent(ItemFrame itemFrame) { - this.itemFrame = itemFrame; - } - -} \ No newline at end of file diff --git a/src/main/java/io/github/rypofalem/armorstandeditor/api/ItemFrameGlowEvent.java b/src/main/java/io/github/rypofalem/armorstandeditor/api/ItemFrameGlowEvent.java deleted file mode 100644 index 7f5cdc97..00000000 --- a/src/main/java/io/github/rypofalem/armorstandeditor/api/ItemFrameGlowEvent.java +++ /dev/null @@ -1,35 +0,0 @@ -package io.github.rypofalem.armorstandeditor.api; - -import lombok.Getter; -import lombok.Setter; - -import org.bukkit.entity.ItemFrame; -import org.bukkit.entity.Player; -import org.bukkit.event.Cancellable; -import org.bukkit.event.HandlerList; - -public class ItemFrameGlowEvent extends ItemFrameEvent implements Cancellable { - @Getter - @Setter - private boolean cancelled = false; - - @Getter - protected final Player player; - - public ItemFrameGlowEvent(ItemFrame itemFrame, Player player) { - super(itemFrame); - this.player = player; - } - - /* Generated for Bukkit */ - private static final HandlerList handlers = new HandlerList(); - - public static HandlerList getHandlerList() { - return (handlers); - } - - @Override - public HandlerList getHandlers() { - return (handlers); - } -} \ No newline at end of file diff --git a/src/main/java/io/github/rypofalem/armorstandeditor/api/ItemFrameManipulatedEvent.java b/src/main/java/io/github/rypofalem/armorstandeditor/api/ItemFrameManipulatedEvent.java deleted file mode 100644 index 9c80c077..00000000 --- a/src/main/java/io/github/rypofalem/armorstandeditor/api/ItemFrameManipulatedEvent.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * ItemFrameEditor: Bukkit plugin to allow editing armor stand attributes - * Copyright (C) 2016-2023 RypoFalem - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package io.github.rypofalem.armorstandeditor.api; - -import lombok.Getter; -import lombok.Setter; - -import org.bukkit.entity.ItemFrame; -import org.bukkit.entity.Player; -import org.bukkit.event.Cancellable; -import org.bukkit.event.HandlerList; - -public class ItemFrameManipulatedEvent extends ItemFrameEvent implements Cancellable { - - @Getter - @Setter - private boolean cancelled = false; - - @Getter - protected final Player player; - - public ItemFrameManipulatedEvent(ItemFrame itemFrame, Player player) { - super(itemFrame); - this.player = player; - } - - /* Generated for Bukkit */ - private static final HandlerList handlers = new HandlerList(); - - public static HandlerList getHandlerList() { - return (handlers); - } - - @Override - public HandlerList getHandlers() { - return (handlers); - } -} - diff --git a/src/main/java/io/github/rypofalem/armorstandeditor/api/ItemFrameTargetedEvent.java b/src/main/java/io/github/rypofalem/armorstandeditor/api/ItemFrameTargetedEvent.java deleted file mode 100644 index 1c9c162c..00000000 --- a/src/main/java/io/github/rypofalem/armorstandeditor/api/ItemFrameTargetedEvent.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * ArmorStandEditor: Bukkit plugin to allow editing armor stand attributes - * Copyright (C) 2016-2023 RypoFalem - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -package io.github.rypofalem.armorstandeditor.api; - -import lombok.Getter; -import lombok.Setter; - -import org.bukkit.entity.ItemFrame; -import org.bukkit.entity.Player; -import org.bukkit.event.Cancellable; -import org.bukkit.event.HandlerList; - -public class ItemFrameTargetedEvent extends ItemFrameEvent implements Cancellable { - @Getter - @Setter - private boolean cancelled = false; - - @Getter - protected final Player player; - - public ItemFrameTargetedEvent(ItemFrame itemFrame, Player player) { - super(itemFrame); - this.player = player; - } - - /* Generated for Bukkit */ - private static final HandlerList handlers = new HandlerList(); - - public static HandlerList getHandlerList() { - return (handlers); - } - - @Override - public HandlerList getHandlers() { - return (handlers); - } -} diff --git a/src/main/java/io/github/rypofalem/armorstandeditor/api/PlayerOpenMenuEvent.java b/src/main/java/io/github/rypofalem/armorstandeditor/api/PlayerOpenMenuEvent.java deleted file mode 100644 index 908b6693..00000000 --- a/src/main/java/io/github/rypofalem/armorstandeditor/api/PlayerOpenMenuEvent.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * ArmorStandEditor: Bukkit plugin to allow editing armor stand attributes - * Copyright (C) 2016-2023 RypoFalem - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package io.github.rypofalem.armorstandeditor.api; - -import lombok.Getter; -import lombok.Setter; - -import org.bukkit.entity.Player; -import org.bukkit.event.Cancellable; -import org.bukkit.event.Event; -import org.bukkit.event.HandlerList; - -public class PlayerOpenMenuEvent extends Event implements Cancellable { - @Getter - @Setter - private boolean cancelled = false; - - @Getter - protected final Player player; - - public PlayerOpenMenuEvent(Player player) { - this.player = player; - } - - /* Generated for Bukkit */ - private static final HandlerList handlers = new HandlerList(); - - public static HandlerList getHandlerList() { - return (handlers); - } - - @Override - public HandlerList getHandlers() { - return (handlers); - } -} \ No newline at end of file diff --git a/src/main/java/io/github/rypofalem/armorstandeditor/language/Language.java b/src/main/java/io/github/rypofalem/armorstandeditor/language/Language.java deleted file mode 100644 index 16b6e783..00000000 --- a/src/main/java/io/github/rypofalem/armorstandeditor/language/Language.java +++ /dev/null @@ -1,136 +0,0 @@ -/* - * ArmorStandEditor: Bukkit plugin to allow editing armor stand attributes - * Copyright (C) 2016-2023 RypoFalem - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - - -package io.github.rypofalem.armorstandeditor.language; - -import io.github.rypofalem.armorstandeditor.ArmorStandEditorPlugin; - -import org.bukkit.ChatColor; -import org.bukkit.configuration.file.YamlConfiguration; - -import java.io.*; -import java.nio.charset.StandardCharsets; - -public class Language { - final String DEFAULT_LANG = "en_US.yml"; - private YamlConfiguration langConfig = null; - private YamlConfiguration defConfig = null; - private File langFile = null; - ArmorStandEditorPlugin plugin; - - public Language(String langFileName, ArmorStandEditorPlugin plugin) { - this.plugin = plugin; - reloadLang(langFileName); - } - - public void reloadLang(String langFileName) { - if (langFileName == null) langFileName = DEFAULT_LANG; - File langFolder = new File(plugin.getDataFolder().getPath() + File.separator + "lang"); - langFile = new File(langFolder, langFileName); - - InputStream input = plugin.getResource("lang" + "/" + DEFAULT_LANG); //getResource doesn't accept File.seperator on windows, need to hardcode unix seperator "/" instead - assert input != null; - Reader defaultLangStream = new InputStreamReader(input, StandardCharsets.UTF_8); - defConfig = YamlConfiguration.loadConfiguration(defaultLangStream); - - input = null; - try { - input = new FileInputStream(langFile); - } catch (FileNotFoundException e) { - e.printStackTrace(); - return; - } - - Reader langStream = new InputStreamReader(input, StandardCharsets.UTF_8); - langConfig = YamlConfiguration.loadConfiguration(langStream); - } - - //path: yml path to message in language file - //format: yml path to format in language file - //option: path-specific variable that may be used - public String getMessage(String path, String format, String option) { - if (langConfig == null) reloadLang(langFile.getName()); - if (path == null) return ""; - if (option == null) option = ""; - - format = getFormat(format); - for (int i = 0; i < format.length(); i += 2) { //place formatting symbol before each character - format = format.substring(0, i) + ChatColor.COLOR_CHAR + format.substring(i); - } - - if (getString(path + "." + option) != null) option = getString(path + "." + option); - String message = format + getString(path + ".msg"); - message = message.replace("", option); - return message; - } - - public String getMessage(String path, String format) { - return getMessage(path, format, null); - } - - public String getMessage(String path) { - return getMessage(path, "info"); - } - - public String getRawMessage(String path, String format, String option) { - String message = ChatColor.stripColor(getMessage(path, format, option)); - format = getFormat(format); - ChatColor color = ChatColor.WHITE; - String bold = "" , italic = "" , underlined = "" , obfuscated = "" , strikethrough = ""; - for (int i = 0; i < format.length(); i++) { - ChatColor code = ChatColor.getByChar(format.charAt(i)); - switch (code) { - case MAGIC: - obfuscated = ", \"obfuscated\": true"; - break; - case BOLD: - bold = ", \"bold\": true"; - break; - case STRIKETHROUGH: - strikethrough = ", \"strikethrough\": true"; - break; - case UNDERLINE: - underlined = ", \"underlined\": true"; - break; - case ITALIC: - italic = ", \"italic\": true"; - break; - default: color = !code.isColor() ? color : code; - } - } - return "{\"text\":\"%s\", \"color\":\"%s\"%s%s%s%s%s}".formatted(message, color.name().toLowerCase(), - obfuscated, bold, strikethrough, underlined, italic); - } - - private String getFormat(String format) { - format = getString(format); - return format == null ? "" : format; - } - - private String getString(String path) { - String message = null; - if (langConfig.contains(path)) { - message = langConfig.getString(path); - } else if (defConfig.contains(path)) { - message = defConfig.getString(path); - } - return message; - } -} \ No newline at end of file diff --git a/src/main/java/io/github/rypofalem/armorstandeditor/menu/ASEHolder.java b/src/main/java/io/github/rypofalem/armorstandeditor/menu/ASEHolder.java deleted file mode 100644 index c5d341cd..00000000 --- a/src/main/java/io/github/rypofalem/armorstandeditor/menu/ASEHolder.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * ArmorStandEditor: Bukkit plugin to allow editing armor stand attributes - * Copyright (C) 2016-2023 RypoFalem - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -package io.github.rypofalem.armorstandeditor.menu; - -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.InventoryHolder; - - -public class ASEHolder implements InventoryHolder { - - @Override - public Inventory getInventory() { - return null; - } - -} diff --git a/src/main/java/io/github/rypofalem/armorstandeditor/menu/EquipmentMenu.java b/src/main/java/io/github/rypofalem/armorstandeditor/menu/EquipmentMenu.java deleted file mode 100644 index 81aa44e7..00000000 --- a/src/main/java/io/github/rypofalem/armorstandeditor/menu/EquipmentMenu.java +++ /dev/null @@ -1,118 +0,0 @@ -/* - * ArmorStandEditor: Bukkit plugin to allow editing armor stand attributes - * Copyright (C) 2016-2023 RypoFalem - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -package io.github.rypofalem.armorstandeditor.menu; - -import io.github.rypofalem.armorstandeditor.PlayerEditor; - -import org.bukkit.Bukkit; -import org.bukkit.Material; -import org.bukkit.entity.ArmorStand; -import org.bukkit.inventory.EntityEquipment; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.ItemFlag; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.ItemMeta; -import org.bukkit.persistence.PersistentDataType; - -import java.util.ArrayList; - -public class EquipmentMenu { - Inventory menuInv; - private PlayerEditor pe; - private ArmorStand armorstand; - static String name = "ArmorStand Equipment"; - ItemStack helmet, chest, pants, feetsies, rightHand, leftHand; - - public EquipmentMenu(PlayerEditor pe, ArmorStand as) { - this.pe = pe; - this.armorstand = as; - name = pe.plugin.getLang().getMessage("equiptitle", "menutitle"); - menuInv = Bukkit.createInventory(pe.getManager().getEquipmentHolder(), 18, name); - } - - private void fillInventory() { - menuInv.clear(); - EntityEquipment equipment = armorstand.getEquipment(); - assert equipment != null; - ItemStack helmet = equipment.getHelmet(); - ItemStack chest = equipment.getChestplate(); - ItemStack pants = equipment.getLeggings(); - ItemStack feetsies = equipment.getBoots(); - ItemStack rightHand = equipment.getItemInMainHand(); - ItemStack leftHand = equipment.getItemInOffHand(); - equipment.clear(); - - ItemStack disabledIcon = new ItemStack(Material.BARRIER); - ItemMeta meta = disabledIcon.getItemMeta(); - meta.setDisplayName(pe.plugin.getLang().getMessage("disabled", "warn")); //equipslot.msg

While this class is neither feature-rich nor the most performant one, it's sufficient enough + * for its use-case. + */ + public static class JsonObjectBuilder { + + private StringBuilder builder = new StringBuilder(); + + private boolean hasAtLeastOneField = false; + + public JsonObjectBuilder() { + builder.append("{"); + } + + /** + * Appends a null field to the JSON. + * + * @param key The key of the field. + * @return A reference to this object. + */ + public JsonObjectBuilder appendNull(String key) { + appendFieldUnescaped(key, "null"); + return this; + } + + /** + * Appends a string field to the JSON. + * + * @param key The key of the field. + * @param value The value of the field. + * @return A reference to this object. + */ + public JsonObjectBuilder appendField(String key, String value) { + if (value == null) { + throw new IllegalArgumentException("JSON value must not be null"); + } + appendFieldUnescaped(key, "\"" + escape(value) + "\""); + return this; + } + + /** + * Appends an integer field to the JSON. + * + * @param key The key of the field. + * @param value The value of the field. + * @return A reference to this object. + */ + public JsonObjectBuilder appendField(String key, int value) { + appendFieldUnescaped(key, String.valueOf(value)); + return this; + } + + /** + * Appends an object to the JSON. + * + * @param key The key of the field. + * @param object The object. + * @return A reference to this object. + */ + public JsonObjectBuilder appendField(String key, JsonObject object) { + if (object == null) { + throw new IllegalArgumentException("JSON object must not be null"); + } + appendFieldUnescaped(key, object.toString()); + return this; + } + + /** + * Appends a string array to the JSON. + * + * @param key The key of the field. + * @param values The string array. + * @return A reference to this object. + */ + public JsonObjectBuilder appendField(String key, String[] values) { + if (values == null) { + throw new IllegalArgumentException("JSON values must not be null"); + } + String escapedValues = + Arrays.stream(values) + .map(value -> "\"" + escape(value) + "\"") + .collect(Collectors.joining(",")); + appendFieldUnescaped(key, "[" + escapedValues + "]"); + return this; + } + + /** + * Appends an integer array to the JSON. + * + * @param key The key of the field. + * @param values The integer array. + * @return A reference to this object. + */ + public JsonObjectBuilder appendField(String key, int[] values) { + if (values == null) { + throw new IllegalArgumentException("JSON values must not be null"); + } + String escapedValues = + Arrays.stream(values).mapToObj(String::valueOf).collect(Collectors.joining(",")); + appendFieldUnescaped(key, "[" + escapedValues + "]"); + return this; + } + + /** + * Appends an object array to the JSON. + * + * @param key The key of the field. + * @param values The integer array. + * @return A reference to this object. + */ + public JsonObjectBuilder appendField(String key, JsonObject[] values) { + if (values == null) { + throw new IllegalArgumentException("JSON values must not be null"); + } + String escapedValues = + Arrays.stream(values).map(JsonObject::toString).collect(Collectors.joining(",")); + appendFieldUnescaped(key, "[" + escapedValues + "]"); + return this; + } + + /** + * Appends a field to the object. + * + * @param key The key of the field. + * @param escapedValue The escaped value of the field. + */ + private void appendFieldUnescaped(String key, String escapedValue) { + if (builder == null) { + throw new IllegalStateException("JSON has already been built"); + } + if (key == null) { + throw new IllegalArgumentException("JSON key must not be null"); + } + if (hasAtLeastOneField) { + builder.append(","); + } + builder.append("\"").append(escape(key)).append("\":").append(escapedValue); + hasAtLeastOneField = true; + } + + /** + * Builds the JSON string and invalidates this builder. + * + * @return The built JSON string. + */ + public JsonObject build() { + if (builder == null) { + throw new IllegalStateException("JSON has already been built"); + } + JsonObject object = new JsonObject(builder.append("}").toString()); + builder = null; + return object; + } + + /** + * Escapes the given string like stated in https://www.ietf.org/rfc/rfc4627.txt. + * + *

This method escapes only the necessary characters '"', '\'. and '\u0000' - '\u001F'. + * Compact escapes are not used (e.g., '\n' is escaped as "\u000a" and not as "\n"). + * + * @param value The value to escape. + * @return The escaped value. + */ + private static String escape(String value) { + final StringBuilder builder = new StringBuilder(); + for (int i = 0; i < value.length(); i++) { + char c = value.charAt(i); + if (c == '"') { + builder.append("\\\""); + } else if (c == '\\') { + builder.append("\\\\"); + } else if (c <= '\u000F') { + builder.append("\\u000").append(Integer.toHexString(c)); + } else if (c <= '\u001F') { + builder.append("\\u00").append(Integer.toHexString(c)); + } else { + builder.append(c); + } + } + return builder.toString(); + } + + /** + * A super simple representation of a JSON object. + * + *

This class only exists to make methods of the {@link JsonObjectBuilder} type-safe and not + * allow a raw string inputs for methods like {@link JsonObjectBuilder#appendField(String, + * JsonObject)}. + */ + public static class JsonObject { + + private final String value; + + private JsonObject(String value) { + this.value = value; + } + + @Override + public String toString() { + return value; + } + } + } +} + diff --git a/src/main/java/io/github/rypofalem/armorstandeditor/Debug.java b/src/main/java/io/github/rypofalem/armorstandeditor/devtools/Debug.java similarity index 81% rename from src/main/java/io/github/rypofalem/armorstandeditor/Debug.java rename to src/main/java/io/github/rypofalem/armorstandeditor/devtools/Debug.java index 385a89bf..eff31da5 100644 --- a/src/main/java/io/github/rypofalem/armorstandeditor/Debug.java +++ b/src/main/java/io/github/rypofalem/armorstandeditor/devtools/Debug.java @@ -1,6 +1,6 @@ -package io.github.rypofalem.armorstandeditor; +package io.github.rypofalem.armorstandeditor.devtools; -import io.rypofalem.armorstandeditor.ArmorStandEditorPlugin; +import io.github.rypofalem.armorstandeditor.ArmorStandEditorPlugin; import java.util.logging.Level; diff --git a/src/main/java/io/github/rypofalem/armorstandeditor/metricshandler/MetricsHandler.java b/src/main/java/io/github/rypofalem/armorstandeditor/metricshandler/MetricsHandler.java new file mode 100644 index 00000000..ed64ad0f --- /dev/null +++ b/src/main/java/io/github/rypofalem/armorstandeditor/metricshandler/MetricsHandler.java @@ -0,0 +1,38 @@ +package io.github.rypofalem.armorstandeditor.metricshandler; + +import io.github.rypofalem.armorstandeditor.ArmorStandEditorPlugin; +import io.github.rypofalem.armorstandeditor.Metrics; + +import static java.lang.String.valueOf; + +public class MetricsHandler { + private static final int PLUGIN_ID = 12668; + public ArmorStandEditorPlugin plugin; + + public MetricsHandler(){ + Metrics metrics = new Metrics(plugin, PLUGIN_ID); + metrics.addCustomChart(new Metrics.SimplePie("dev_flag_enabled", () -> valueOf(plugin.isDebug()))); + metrics.addCustomChart(new Metrics.SimplePie("require_sneaking", () -> valueOf(plugin.getRequireSneakingConfig()))); + metrics.addCustomChart(new Metrics.SimplePie("tool_lore_enabled", () -> valueOf(plugin.getRequireToolLoreConfig()))); + metrics.addCustomChart(new Metrics.SimplePie("tool_data_enabled", () -> valueOf(plugin.getRequireToolDataConfig()))); + metrics.addCustomChart(new Metrics.SimplePie("custom_toolname_enabled", () -> valueOf(plugin.getRequireToolNameConfig()))); + metrics.addCustomChart(new Metrics.SimplePie("per_world_enabled", () -> valueOf(plugin.getPerWorldSupportConfig()))); + metrics.addCustomChart(new Metrics.SimplePie("armor_stand_invisiblity_usage", () -> valueOf(plugin.getInvisibleArmorStandsConfig()))); + metrics.addCustomChart(new Metrics.SimplePie("itemframe_invisiblity_usage", () -> valueOf(plugin.getInvisibleItemFramesConfig()))); + metrics.addCustomChart(new Metrics.SimplePie("coarse_rotation_setting", () -> String.valueOf(plugin.getCoarseConfig()))); + metrics.addCustomChart(new Metrics.SimplePie("fine_rotation_setting", () -> String.valueOf(plugin.getFineConfig()))); + metrics.addCustomChart(new Metrics.SimplePie("min_supported_scale_setting", () -> String.valueOf(plugin.getMinScaleConfig()))); + metrics.addCustomChart(new Metrics.SimplePie("max_supported_scale_setting", () -> String.valueOf(plugin.getMaxScaleConfig()))); + + + //TODO: Readd Languages here! + + + } + + + + + + +} From 228a998c5248e766051b16315cbb9f7fc4e6bc73 Mon Sep 17 00:00:00 2001 From: Wolfieheart Date: Fri, 3 Jan 2025 20:49:30 +0100 Subject: [PATCH 10/40] [CORE] Fix Rewrite Build Break Signed-off-by: Wolfieheart --- pom.xml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index dbe3d51a..7d43143e 100644 --- a/pom.xml +++ b/pom.xml @@ -11,7 +11,7 @@ 21 UTF-8 - 3.0.1 + 3.1.1 wolfieheart https://sonarcloud.io @@ -79,9 +79,10 @@ org.apache.maven.plugins maven-compiler-plugin - 3.12.0 + 3.13.0 - ${java.version} + ${java.version} + ${java.version} From 7d12c76858441e7d5bc2207728cf9ab81dae303c Mon Sep 17 00:00:00 2001 From: Wolfieheart Date: Fri, 3 Jan 2025 20:52:50 +0100 Subject: [PATCH 11/40] [CORE] Fix Rewrite Build Break Signed-off-by: Wolfieheart --- .github/workflows/maven-publish.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/maven-publish.yml b/.github/workflows/maven-publish.yml index 03abd383..35422912 100644 --- a/.github/workflows/maven-publish.yml +++ b/.github/workflows/maven-publish.yml @@ -10,7 +10,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - java: ['17', '21'] + java: ['21','23'] steps: # 1. Check out the current working tree - name: Checkout ArmorStandEditor Repository From 52f7434c504f8842e5e4a9fe30733862c70a5a2c Mon Sep 17 00:00:00 2001 From: Wolfieheart Date: Fri, 3 Jan 2025 20:56:44 +0100 Subject: [PATCH 12/40] [CORE] Fix Rewrite Build Break (Only do Java 21 Artifacts - Not Java 23.... YET!) Signed-off-by: Wolfieheart --- .github/workflows/maven-publish.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/maven-publish.yml b/.github/workflows/maven-publish.yml index 35422912..740674a8 100644 --- a/.github/workflows/maven-publish.yml +++ b/.github/workflows/maven-publish.yml @@ -10,7 +10,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - java: ['21','23'] + java: ['21', '23'] steps: # 1. Check out the current working tree - name: Checkout ArmorStandEditor Repository @@ -57,6 +57,7 @@ jobs: #6 Upload Artifacts (Debug Purposes) - name: Upload Artifact for Debugging uses: actions/upload-artifact@v4.0.0 + if: success() && matrix.java == '21' with: name: artifact path: /home/runner/work/ArmorStandEditor/ArmorStandEditor/target/armorstandeditor-*-*.jar From 9ef2f627dcdcb3622e9e9a1d9943dfb78738ee9a Mon Sep 17 00:00:00 2001 From: Wolfieheart Date: Fri, 3 Jan 2025 21:22:00 +0100 Subject: [PATCH 13/40] [CORE] Re-Implement Languages and Lay the placeholders for Menus/Better Menus Signed-off-by: Wolfieheart --- TODO_Rewrite.md | 32 ++++--- .../armorstandeditor/language/Lang.java | 84 +++++++++++++++++++ .../armorstandeditor/menu/ASEHolder.java | 7 ++ .../armorstandeditor/menu/EditorMenu.java | 8 ++ 4 files changed, 119 insertions(+), 12 deletions(-) create mode 100644 src/main/java/io/github/rypofalem/armorstandeditor/language/Lang.java create mode 100644 src/main/java/io/github/rypofalem/armorstandeditor/menu/ASEHolder.java create mode 100644 src/main/java/io/github/rypofalem/armorstandeditor/menu/EditorMenu.java diff --git a/TODO_Rewrite.md b/TODO_Rewrite.md index 3a5c5716..de470f1c 100644 --- a/TODO_Rewrite.md +++ b/TODO_Rewrite.md @@ -1,15 +1,23 @@ -# List of everything to be readded to ArmorStandEditor +# What Still has to be rewritten +


-## Priority 1 - CRITICAL / SEVERE -- Commands -- Player Editing - -## Priority 2 - Normal -- Languages -- Reimplement what was already there previously -- Retrieving own Player Head Support +## In Progress +- Menus from 1.21.4-48 -## Priority 3 - Low +## TODO: +- Player Editor Reimplementation +- Utils +- Modes +- Commands +- Permissions +- API +- Protections +- Folia Support -## Priority 4 - Minor -- Custom Data pack Model Support \ No newline at end of file +## Done +- Configuration Options and Loading them in +- Scoreboards +- SpigotMC check / PaperMc and Fork Checks +- Metrics and Handling them +- Debug Output +- Langauges \ No newline at end of file diff --git a/src/main/java/io/github/rypofalem/armorstandeditor/language/Lang.java b/src/main/java/io/github/rypofalem/armorstandeditor/language/Lang.java new file mode 100644 index 00000000..57b9a69e --- /dev/null +++ b/src/main/java/io/github/rypofalem/armorstandeditor/language/Lang.java @@ -0,0 +1,84 @@ +package io.github.rypofalem.armorstandeditor.language; + +import io.github.rypofalem.armorstandeditor.ArmorStandEditorPlugin; +import org.bukkit.configuration.file.YamlConfiguration; + +import java.io.*; +import java.nio.charset.StandardCharsets; + +public class Lang { + + protected static final String DEFAULT_LANG = "en_us.yml"; + protected final ArmorStandEditorPlugin plugin; + private YamlConfiguration langConfig = null; + private YamlConfiguration defConfig = null; + private File langFile = null; + + + public Lang(final String langFilename, ArmorStandEditorPlugin plugin) { + this.plugin = plugin; + reloadLang(langFilename); + } + + public void reloadLang(String langFileName){ + if(langFileName == null) langFileName = DEFAULT_LANG; + File langFolder = new File(plugin.getDataFolder().getPath() + File.separator + "lang"); + langFile = new File(langFolder, langFileName); + InputStream inputStream = plugin.getResource("lang" + "/" + DEFAULT_LANG); + Reader defaultLangStream = new InputStreamReader(inputStream, StandardCharsets.UTF_8); + defConfig = YamlConfiguration.loadConfiguration(defaultLangStream); + inputStream = null; + try{ + inputStream = new FileInputStream(langFile); + } catch (FileNotFoundException e){ + e.printStackTrace(); + return; + } + Reader langStream = new InputStreamReader(inputStream, StandardCharsets.UTF_8); + langConfig = YamlConfiguration.loadConfiguration(langStream); + } + + //path: yml path to message in language file + //format: yml path to format in language file + //option: path-specific variable that may be used + public String getMessage(String path, String format, String option) { + if (langConfig == null) reloadLang(langFile.getName()); + if (path == null) return ""; + if (option == null) option = ""; + + format = getFormat(format); + for (int i = 0; i < format.length(); i += 2) { //place formatting symbol before each character + format = format.substring(0, i) + '\u00A7' + format.substring(i); + } + + if (getString(path + "." + option) != null) option = getString(path + "." + option); + String message = format + getString(path + ".msg"); + message = message.replace("", option); + return message; + } + + + public String getMessage(String path, String format) { + return getMessage(path, format, null); + } + + public String getMessage(String path) { + return getMessage(path, "info"); + } + + private String getFormat(String format) { + format = getString(format); + return format == null ? "" : format; + } + + private String getString(String path) { + String message = null; + if (langConfig.contains(path)) { + message = langConfig.getString(path); + } else if (defConfig.contains(path)) { + message = defConfig.getString(path); + } + return message; + } + +} diff --git a/src/main/java/io/github/rypofalem/armorstandeditor/menu/ASEHolder.java b/src/main/java/io/github/rypofalem/armorstandeditor/menu/ASEHolder.java new file mode 100644 index 00000000..7726732f --- /dev/null +++ b/src/main/java/io/github/rypofalem/armorstandeditor/menu/ASEHolder.java @@ -0,0 +1,7 @@ +package io.github.rypofalem.armorstandeditor.menu; + +import org.bukkit.inventory.InventoryHolder; +import org.bukkit.inventory.Inventory; + +public interface ASEHolder extends InventoryHolder { +} diff --git a/src/main/java/io/github/rypofalem/armorstandeditor/menu/EditorMenu.java b/src/main/java/io/github/rypofalem/armorstandeditor/menu/EditorMenu.java new file mode 100644 index 00000000..69fb452d --- /dev/null +++ b/src/main/java/io/github/rypofalem/armorstandeditor/menu/EditorMenu.java @@ -0,0 +1,8 @@ +package io.github.rypofalem.armorstandeditor.menu; + +import org.bukkit.entity.ArmorStand; + +public interface EditorMenu extends ASEHolder{ + void open(); + ArmorStand getArmorStand(); +} From dd7e0a5f4aa1487ad1f7c4516d35229c9e22b690 Mon Sep 17 00:00:00 2001 From: Wolfieheart Date: Fri, 3 Jan 2025 22:50:32 +0100 Subject: [PATCH 14/40] [CORE] Rollback and add in Utils and Scheduler Signed-off-by: Wolfieheart --- TODO_Rewrite.md | 15 +++- .../armorstandeditor/util/Scheduler.java | 80 +++++++++++++++++++ .../rypofalem/armorstandeditor/util/Util.java | 50 ++++++++++++ 3 files changed, 142 insertions(+), 3 deletions(-) create mode 100644 src/main/java/io/github/rypofalem/armorstandeditor/util/Scheduler.java create mode 100644 src/main/java/io/github/rypofalem/armorstandeditor/util/Util.java diff --git a/TODO_Rewrite.md b/TODO_Rewrite.md index de470f1c..b5ee9089 100644 --- a/TODO_Rewrite.md +++ b/TODO_Rewrite.md @@ -2,17 +2,26 @@
## In Progress -- Menus from 1.21.4-48 +- Utils +- Folia Support ## TODO: +- Menus from 1.21.4-48 + - Sizing Rework + - Preset poses + - Standard ASE Menu + - Equipment - Player Editor Reimplementation -- Utils + - Start with Menu Critical things + - Modes - Commands - Permissions - API + - Add New APIs for Menu Opening. + - Readd everything there currently. - Protections -- Folia Support + ## Done - Configuration Options and Loading them in diff --git a/src/main/java/io/github/rypofalem/armorstandeditor/util/Scheduler.java b/src/main/java/io/github/rypofalem/armorstandeditor/util/Scheduler.java new file mode 100644 index 00000000..f2f59d72 --- /dev/null +++ b/src/main/java/io/github/rypofalem/armorstandeditor/util/Scheduler.java @@ -0,0 +1,80 @@ +package io.github.rypofalem.armorstandeditor.util; + +import static io.github.rypofalem.armorstandeditor.ArmorStandEditorPlugin.isFolia; + +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.entity.Entity; +import org.bukkit.plugin.Plugin; + +import java.util.function.Consumer; + +public class Scheduler { + private static Object GLOBAL_REGION_SCHEDULER = null; + + public static T callMethod(Class clazz, Object object, String methodName, Class[] parameterTypes, Object... args) { + try { + return (T) clazz.getDeclaredMethod(methodName, parameterTypes).invoke(object, args); + } catch (Throwable t) { + throw new IllegalStateException(t); + } + } + + public static T callMethod(Object object, String methodName, Class[] parameterTypes, Object... args) { + return callMethod(object.getClass(), object, methodName, parameterTypes, args); + } + + public static T callMethod(Class clazz, String methodName) { + return callMethod(clazz, null, methodName, new Class[]{}); + } + + private static boolean methodExist(Class clazz, String methodName, Class... parameterTypes) { + try { + clazz.getDeclaredMethod(methodName, parameterTypes); + return true; + } catch (Throwable ignored) { + } + return false; + } + + public static Object getGlobalRegionScheduler() { + if (GLOBAL_REGION_SCHEDULER == null) { + GLOBAL_REGION_SCHEDULER = callMethod(Bukkit.class, "getGlobalRegionScheduler"); + } + return GLOBAL_REGION_SCHEDULER; + } + + public static void runTask(Plugin plugin, Runnable runnable) { + if (isFolia()) { + Object globalRegionScheduler = getGlobalRegionScheduler(); + callMethod(globalRegionScheduler, "run", new Class[]{Plugin.class, Consumer.class}, plugin, (Consumer) (task) -> runnable.run()); + return; + } + Bukkit.getScheduler().runTask(plugin, runnable); + } + + public static void runTaskTimer(Plugin plugin, Runnable runnable, long initialDelayTicks, long periodTicks) { + if (isFolia()) { + Object globalRegionScheduler = getGlobalRegionScheduler(); + callMethod(globalRegionScheduler, "runAtFixedRate", new Class[]{Plugin.class, Consumer.class, long.class, long.class}, + plugin, (Consumer) (task) -> runnable.run(), initialDelayTicks, periodTicks); + return; + } + Bukkit.getScheduler().runTaskTimerAsynchronously(plugin, runnable, initialDelayTicks, periodTicks); + } + + public static void runTaskLater(Plugin plugin, Runnable runnable, long delayedTicks) { + if (isFolia()) { + Object globalRegionScheduler = getGlobalRegionScheduler(); + callMethod(globalRegionScheduler, "runDelayed", new Class[]{Plugin.class, Consumer.class, long.class}, + plugin, (Consumer) (task) -> runnable.run(), delayedTicks); + return; + } + Bukkit.getScheduler().runTaskLater(plugin, runnable, delayedTicks); + } + + public static void teleport(Entity entity, Location location) { + if (isFolia()) callMethod(Entity.class, entity, "teleportAsync", new Class[]{Location.class}, location); + else entity.teleport(location); + } +} diff --git a/src/main/java/io/github/rypofalem/armorstandeditor/util/Util.java b/src/main/java/io/github/rypofalem/armorstandeditor/util/Util.java new file mode 100644 index 00000000..dd362a3b --- /dev/null +++ b/src/main/java/io/github/rypofalem/armorstandeditor/util/Util.java @@ -0,0 +1,50 @@ +package io.github.rypofalem.armorstandeditor.util; + +public abstract class Util { + + public static final double FULL_CIRCLE = Math.PI * 2; + + public static > String getEnumList(Class enumType) { + return getEnumList(enumType, " | "); + } + + public static > String getEnumList(Class enumType, String delimiter) { + StringBuilder list = new StringBuilder(); + boolean put = false; + for (Enum e : enumType.getEnumConstants()) { + list.append(e.toString()).append(delimiter); + put = true; + } + if (put) list = new StringBuilder(list.substring(0, list.length() - delimiter.length())); + return list.toString(); + } + + public static double addAngle(double current, double angleChange) { + current += angleChange; + current = fixAngle(current, angleChange); + return current; + } + + public static double subAngle(double current, double angleChange) { + current -= angleChange; + current = fixAngle(current, angleChange); + return current; + } + + //clamps angle to 0 if it exceeds 2PI rad (360 degrees), is closer to 0 than angleChange value, or is closer to 2PI rad than 2PI rad - angleChange value. + private static double fixAngle(double angle, double angleChange) { + if (angle > FULL_CIRCLE) { + return 0; + } + + if (angle > 0 && angle < angleChange && angle < angleChange / 2) { + return 0; + } + + if (angle > FULL_CIRCLE - angle && angle > FULL_CIRCLE - (angleChange / 2)) { + return 0; + } + + return angle; + } +} \ No newline at end of file From d990081c978ce0bbb9ca6b332eb19a3f1a8b9c3e Mon Sep 17 00:00:00 2001 From: Wolfieheart Date: Fri, 3 Jan 2025 22:54:47 +0100 Subject: [PATCH 15/40] [CORE] Readd in Existing APIs Signed-off-by: Wolfieheart --- TODO_Rewrite.md | 16 ++--- pom.xml | 9 ++- .../armorstandeditor/api/ArmorStandEvent.java | 36 +++++++++++ .../api/ArmorStandManipulatedEvent.java | 54 +++++++++++++++++ .../api/ArmorStandRenameEvent.java | 59 +++++++++++++++++++ .../api/ArmorStandTargetedEvent.java | 54 +++++++++++++++++ .../armorstandeditor/api/ItemFrameEvent.java | 36 +++++++++++ .../api/ItemFrameGlowEvent.java | 35 +++++++++++ .../api/ItemFrameManipulatedEvent.java | 55 +++++++++++++++++ .../api/ItemFrameTargetedEvent.java | 54 +++++++++++++++++ .../api/PlayerOpenMenuEvent.java | 52 ++++++++++++++++ 11 files changed, 451 insertions(+), 9 deletions(-) create mode 100644 src/main/java/io/github/rypofalem/armorstandeditor/api/ArmorStandEvent.java create mode 100644 src/main/java/io/github/rypofalem/armorstandeditor/api/ArmorStandManipulatedEvent.java create mode 100644 src/main/java/io/github/rypofalem/armorstandeditor/api/ArmorStandRenameEvent.java create mode 100644 src/main/java/io/github/rypofalem/armorstandeditor/api/ArmorStandTargetedEvent.java create mode 100644 src/main/java/io/github/rypofalem/armorstandeditor/api/ItemFrameEvent.java create mode 100644 src/main/java/io/github/rypofalem/armorstandeditor/api/ItemFrameGlowEvent.java create mode 100644 src/main/java/io/github/rypofalem/armorstandeditor/api/ItemFrameManipulatedEvent.java create mode 100644 src/main/java/io/github/rypofalem/armorstandeditor/api/ItemFrameTargetedEvent.java create mode 100644 src/main/java/io/github/rypofalem/armorstandeditor/api/PlayerOpenMenuEvent.java diff --git a/TODO_Rewrite.md b/TODO_Rewrite.md index b5ee9089..81ce95bf 100644 --- a/TODO_Rewrite.md +++ b/TODO_Rewrite.md @@ -2,8 +2,9 @@
## In Progress -- Utils -- Folia Support +- API + - Add New APIs for Menu Opening. + - Readd everything there currently. (DONE) ## TODO: - Menus from 1.21.4-48 @@ -12,14 +13,11 @@ - Standard ASE Menu - Equipment - Player Editor Reimplementation - - Start with Menu Critical things - + - Start with Menu Critical things - Modes - Commands - Permissions -- API - - Add New APIs for Menu Opening. - - Readd everything there currently. + - Protections @@ -29,4 +27,6 @@ - SpigotMC check / PaperMc and Fork Checks - Metrics and Handling them - Debug Output -- Langauges \ No newline at end of file +- Langauges +- Utils +- Folia Support \ No newline at end of file diff --git a/pom.xml b/pom.xml index 7d43143e..3e052eb4 100644 --- a/pom.xml +++ b/pom.xml @@ -42,13 +42,20 @@ - + io.papermc.paper paper-api 1.21.4-R0.1-SNAPSHOT provided + + + org.projectlombok + lombok + 1.18.34 + provided + diff --git a/src/main/java/io/github/rypofalem/armorstandeditor/api/ArmorStandEvent.java b/src/main/java/io/github/rypofalem/armorstandeditor/api/ArmorStandEvent.java new file mode 100644 index 00000000..e82445c1 --- /dev/null +++ b/src/main/java/io/github/rypofalem/armorstandeditor/api/ArmorStandEvent.java @@ -0,0 +1,36 @@ +/* + * ArmorStandEditor: Bukkit plugin to allow editing armor stand attributes + * Copyright (C) 2016-2023 RypoFalem + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +package io.github.rypofalem.armorstandeditor.api; + +import lombok.Getter; + +import org.bukkit.entity.ArmorStand; +import org.bukkit.event.Event; + +public abstract class ArmorStandEvent extends Event { + + @Getter + protected final ArmorStand armorStand; + + public ArmorStandEvent(ArmorStand armorStand) { + this.armorStand = armorStand; + } + +} \ No newline at end of file diff --git a/src/main/java/io/github/rypofalem/armorstandeditor/api/ArmorStandManipulatedEvent.java b/src/main/java/io/github/rypofalem/armorstandeditor/api/ArmorStandManipulatedEvent.java new file mode 100644 index 00000000..9df80d7a --- /dev/null +++ b/src/main/java/io/github/rypofalem/armorstandeditor/api/ArmorStandManipulatedEvent.java @@ -0,0 +1,54 @@ +/* + * ArmorStandEditor: Bukkit plugin to allow editing armor stand attributes + * Copyright (C) 2016-2023 RypoFalem + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package io.github.rypofalem.armorstandeditor.api; + +import lombok.Getter; +import lombok.Setter; + +import org.bukkit.entity.ArmorStand; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; + +public class ArmorStandManipulatedEvent extends ArmorStandEvent implements Cancellable { + + @Getter + @Setter + private boolean cancelled = false; + + @Getter + protected final Player player; + + public ArmorStandManipulatedEvent(ArmorStand armorStand, Player player) { + super(armorStand); + this.player = player; + } + + /* Generated for Bukkit */ + private static final HandlerList handlers = new HandlerList(); + + public static HandlerList getHandlerList() { + return (handlers); + } + + @Override + public HandlerList getHandlers() { + return (handlers); + } +} diff --git a/src/main/java/io/github/rypofalem/armorstandeditor/api/ArmorStandRenameEvent.java b/src/main/java/io/github/rypofalem/armorstandeditor/api/ArmorStandRenameEvent.java new file mode 100644 index 00000000..5b243872 --- /dev/null +++ b/src/main/java/io/github/rypofalem/armorstandeditor/api/ArmorStandRenameEvent.java @@ -0,0 +1,59 @@ +/* + * ArmorStandEditor: Bukkit plugin to allow editing armor stand attributes + * Copyright (C) 2016-2023 RypoFalem + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package io.github.rypofalem.armorstandeditor.api; + +import lombok.Getter; +import lombok.Setter; + +import org.bukkit.entity.ArmorStand; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; + +public class ArmorStandRenameEvent extends ArmorStandEvent implements Cancellable { + + @Getter + @Setter + private boolean cancelled = false; + @Getter + @Setter + protected String name; + + @Getter + protected final Player player; + + public ArmorStandRenameEvent(ArmorStand armorStand, Player player, String name) { + super(armorStand); + this.player = player; + this.name = name; + } + + /* Generated for Bukkit */ + private static final HandlerList handlers = new HandlerList(); + + public static HandlerList getHandlerList() { + return (handlers); + } + + @Override + public HandlerList getHandlers() { + return (handlers); + } + +} diff --git a/src/main/java/io/github/rypofalem/armorstandeditor/api/ArmorStandTargetedEvent.java b/src/main/java/io/github/rypofalem/armorstandeditor/api/ArmorStandTargetedEvent.java new file mode 100644 index 00000000..196a039e --- /dev/null +++ b/src/main/java/io/github/rypofalem/armorstandeditor/api/ArmorStandTargetedEvent.java @@ -0,0 +1,54 @@ +/* + * ArmorStandEditor: Bukkit plugin to allow editing armor stand attributes + * Copyright (C) 2016-2023 RypoFalem + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +package io.github.rypofalem.armorstandeditor.api; + +import lombok.Getter; +import lombok.Setter; + +import org.bukkit.entity.ArmorStand; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; + +public class ArmorStandTargetedEvent extends ArmorStandEvent implements Cancellable { + @Getter + @Setter + private boolean cancelled = false; + + @Getter + protected final Player player; + + public ArmorStandTargetedEvent(ArmorStand armorStand, Player player) { + super(armorStand); + this.player = player; + } + + /* Generated for Bukkit */ + private static final HandlerList handlers = new HandlerList(); + + public static HandlerList getHandlerList() { + return (handlers); + } + + @Override + public HandlerList getHandlers() { + return (handlers); + } +} \ No newline at end of file diff --git a/src/main/java/io/github/rypofalem/armorstandeditor/api/ItemFrameEvent.java b/src/main/java/io/github/rypofalem/armorstandeditor/api/ItemFrameEvent.java new file mode 100644 index 00000000..d6358613 --- /dev/null +++ b/src/main/java/io/github/rypofalem/armorstandeditor/api/ItemFrameEvent.java @@ -0,0 +1,36 @@ +/* + * ArmorStandEditor: Bukkit plugin to allow editing armor stand attributes + * Copyright (C) 2016-2023 RypoFalem + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +package io.github.rypofalem.armorstandeditor.api; + +import lombok.Getter; + +import org.bukkit.entity.ItemFrame; +import org.bukkit.event.Event; + +public abstract class ItemFrameEvent extends Event { + + @Getter + protected final ItemFrame itemFrame; + + public ItemFrameEvent(ItemFrame itemFrame) { + this.itemFrame = itemFrame; + } + +} \ No newline at end of file diff --git a/src/main/java/io/github/rypofalem/armorstandeditor/api/ItemFrameGlowEvent.java b/src/main/java/io/github/rypofalem/armorstandeditor/api/ItemFrameGlowEvent.java new file mode 100644 index 00000000..7f5cdc97 --- /dev/null +++ b/src/main/java/io/github/rypofalem/armorstandeditor/api/ItemFrameGlowEvent.java @@ -0,0 +1,35 @@ +package io.github.rypofalem.armorstandeditor.api; + +import lombok.Getter; +import lombok.Setter; + +import org.bukkit.entity.ItemFrame; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; + +public class ItemFrameGlowEvent extends ItemFrameEvent implements Cancellable { + @Getter + @Setter + private boolean cancelled = false; + + @Getter + protected final Player player; + + public ItemFrameGlowEvent(ItemFrame itemFrame, Player player) { + super(itemFrame); + this.player = player; + } + + /* Generated for Bukkit */ + private static final HandlerList handlers = new HandlerList(); + + public static HandlerList getHandlerList() { + return (handlers); + } + + @Override + public HandlerList getHandlers() { + return (handlers); + } +} \ No newline at end of file diff --git a/src/main/java/io/github/rypofalem/armorstandeditor/api/ItemFrameManipulatedEvent.java b/src/main/java/io/github/rypofalem/armorstandeditor/api/ItemFrameManipulatedEvent.java new file mode 100644 index 00000000..9c80c077 --- /dev/null +++ b/src/main/java/io/github/rypofalem/armorstandeditor/api/ItemFrameManipulatedEvent.java @@ -0,0 +1,55 @@ +/* + * ItemFrameEditor: Bukkit plugin to allow editing armor stand attributes + * Copyright (C) 2016-2023 RypoFalem + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package io.github.rypofalem.armorstandeditor.api; + +import lombok.Getter; +import lombok.Setter; + +import org.bukkit.entity.ItemFrame; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; + +public class ItemFrameManipulatedEvent extends ItemFrameEvent implements Cancellable { + + @Getter + @Setter + private boolean cancelled = false; + + @Getter + protected final Player player; + + public ItemFrameManipulatedEvent(ItemFrame itemFrame, Player player) { + super(itemFrame); + this.player = player; + } + + /* Generated for Bukkit */ + private static final HandlerList handlers = new HandlerList(); + + public static HandlerList getHandlerList() { + return (handlers); + } + + @Override + public HandlerList getHandlers() { + return (handlers); + } +} + diff --git a/src/main/java/io/github/rypofalem/armorstandeditor/api/ItemFrameTargetedEvent.java b/src/main/java/io/github/rypofalem/armorstandeditor/api/ItemFrameTargetedEvent.java new file mode 100644 index 00000000..1c9c162c --- /dev/null +++ b/src/main/java/io/github/rypofalem/armorstandeditor/api/ItemFrameTargetedEvent.java @@ -0,0 +1,54 @@ +/* + * ArmorStandEditor: Bukkit plugin to allow editing armor stand attributes + * Copyright (C) 2016-2023 RypoFalem + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +package io.github.rypofalem.armorstandeditor.api; + +import lombok.Getter; +import lombok.Setter; + +import org.bukkit.entity.ItemFrame; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; + +public class ItemFrameTargetedEvent extends ItemFrameEvent implements Cancellable { + @Getter + @Setter + private boolean cancelled = false; + + @Getter + protected final Player player; + + public ItemFrameTargetedEvent(ItemFrame itemFrame, Player player) { + super(itemFrame); + this.player = player; + } + + /* Generated for Bukkit */ + private static final HandlerList handlers = new HandlerList(); + + public static HandlerList getHandlerList() { + return (handlers); + } + + @Override + public HandlerList getHandlers() { + return (handlers); + } +} diff --git a/src/main/java/io/github/rypofalem/armorstandeditor/api/PlayerOpenMenuEvent.java b/src/main/java/io/github/rypofalem/armorstandeditor/api/PlayerOpenMenuEvent.java new file mode 100644 index 00000000..908b6693 --- /dev/null +++ b/src/main/java/io/github/rypofalem/armorstandeditor/api/PlayerOpenMenuEvent.java @@ -0,0 +1,52 @@ +/* + * ArmorStandEditor: Bukkit plugin to allow editing armor stand attributes + * Copyright (C) 2016-2023 RypoFalem + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package io.github.rypofalem.armorstandeditor.api; + +import lombok.Getter; +import lombok.Setter; + +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +public class PlayerOpenMenuEvent extends Event implements Cancellable { + @Getter + @Setter + private boolean cancelled = false; + + @Getter + protected final Player player; + + public PlayerOpenMenuEvent(Player player) { + this.player = player; + } + + /* Generated for Bukkit */ + private static final HandlerList handlers = new HandlerList(); + + public static HandlerList getHandlerList() { + return (handlers); + } + + @Override + public HandlerList getHandlers() { + return (handlers); + } +} \ No newline at end of file From 36218db2b2a429bae382ec6614de8be67ab21d4c Mon Sep 17 00:00:00 2001 From: Wolfieheart Date: Fri, 3 Jan 2025 23:11:59 +0100 Subject: [PATCH 16/40] [CORE] Remove broken APIs - BACK TO TODO1 Sadge Signed-off-by: Wolfieheart --- pom.xml | 2 +- .../api/ArmorStandManipulatedEvent.java | 54 ----------------- .../api/ArmorStandRenameEvent.java | 59 ------------------- .../api/ArmorStandTargetedEvent.java | 54 ----------------- .../api/ItemFrameGlowEvent.java | 35 ----------- .../api/ItemFrameManipulatedEvent.java | 55 ----------------- .../api/ItemFrameTargetedEvent.java | 54 ----------------- .../api/PlayerOpenMenuEvent.java | 52 ---------------- 8 files changed, 1 insertion(+), 364 deletions(-) delete mode 100644 src/main/java/io/github/rypofalem/armorstandeditor/api/ArmorStandManipulatedEvent.java delete mode 100644 src/main/java/io/github/rypofalem/armorstandeditor/api/ArmorStandRenameEvent.java delete mode 100644 src/main/java/io/github/rypofalem/armorstandeditor/api/ArmorStandTargetedEvent.java delete mode 100644 src/main/java/io/github/rypofalem/armorstandeditor/api/ItemFrameGlowEvent.java delete mode 100644 src/main/java/io/github/rypofalem/armorstandeditor/api/ItemFrameManipulatedEvent.java delete mode 100644 src/main/java/io/github/rypofalem/armorstandeditor/api/ItemFrameTargetedEvent.java delete mode 100644 src/main/java/io/github/rypofalem/armorstandeditor/api/PlayerOpenMenuEvent.java diff --git a/pom.xml b/pom.xml index 3e052eb4..33405638 100644 --- a/pom.xml +++ b/pom.xml @@ -46,7 +46,7 @@ io.papermc.paper paper-api - 1.21.4-R0.1-SNAPSHOT + 1.21.1-R0.1-SNAPSHOT provided diff --git a/src/main/java/io/github/rypofalem/armorstandeditor/api/ArmorStandManipulatedEvent.java b/src/main/java/io/github/rypofalem/armorstandeditor/api/ArmorStandManipulatedEvent.java deleted file mode 100644 index 9df80d7a..00000000 --- a/src/main/java/io/github/rypofalem/armorstandeditor/api/ArmorStandManipulatedEvent.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * ArmorStandEditor: Bukkit plugin to allow editing armor stand attributes - * Copyright (C) 2016-2023 RypoFalem - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package io.github.rypofalem.armorstandeditor.api; - -import lombok.Getter; -import lombok.Setter; - -import org.bukkit.entity.ArmorStand; -import org.bukkit.entity.Player; -import org.bukkit.event.Cancellable; -import org.bukkit.event.HandlerList; - -public class ArmorStandManipulatedEvent extends ArmorStandEvent implements Cancellable { - - @Getter - @Setter - private boolean cancelled = false; - - @Getter - protected final Player player; - - public ArmorStandManipulatedEvent(ArmorStand armorStand, Player player) { - super(armorStand); - this.player = player; - } - - /* Generated for Bukkit */ - private static final HandlerList handlers = new HandlerList(); - - public static HandlerList getHandlerList() { - return (handlers); - } - - @Override - public HandlerList getHandlers() { - return (handlers); - } -} diff --git a/src/main/java/io/github/rypofalem/armorstandeditor/api/ArmorStandRenameEvent.java b/src/main/java/io/github/rypofalem/armorstandeditor/api/ArmorStandRenameEvent.java deleted file mode 100644 index 5b243872..00000000 --- a/src/main/java/io/github/rypofalem/armorstandeditor/api/ArmorStandRenameEvent.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * ArmorStandEditor: Bukkit plugin to allow editing armor stand attributes - * Copyright (C) 2016-2023 RypoFalem - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package io.github.rypofalem.armorstandeditor.api; - -import lombok.Getter; -import lombok.Setter; - -import org.bukkit.entity.ArmorStand; -import org.bukkit.entity.Player; -import org.bukkit.event.Cancellable; -import org.bukkit.event.HandlerList; - -public class ArmorStandRenameEvent extends ArmorStandEvent implements Cancellable { - - @Getter - @Setter - private boolean cancelled = false; - @Getter - @Setter - protected String name; - - @Getter - protected final Player player; - - public ArmorStandRenameEvent(ArmorStand armorStand, Player player, String name) { - super(armorStand); - this.player = player; - this.name = name; - } - - /* Generated for Bukkit */ - private static final HandlerList handlers = new HandlerList(); - - public static HandlerList getHandlerList() { - return (handlers); - } - - @Override - public HandlerList getHandlers() { - return (handlers); - } - -} diff --git a/src/main/java/io/github/rypofalem/armorstandeditor/api/ArmorStandTargetedEvent.java b/src/main/java/io/github/rypofalem/armorstandeditor/api/ArmorStandTargetedEvent.java deleted file mode 100644 index 196a039e..00000000 --- a/src/main/java/io/github/rypofalem/armorstandeditor/api/ArmorStandTargetedEvent.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * ArmorStandEditor: Bukkit plugin to allow editing armor stand attributes - * Copyright (C) 2016-2023 RypoFalem - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -package io.github.rypofalem.armorstandeditor.api; - -import lombok.Getter; -import lombok.Setter; - -import org.bukkit.entity.ArmorStand; -import org.bukkit.entity.Player; -import org.bukkit.event.Cancellable; -import org.bukkit.event.HandlerList; - -public class ArmorStandTargetedEvent extends ArmorStandEvent implements Cancellable { - @Getter - @Setter - private boolean cancelled = false; - - @Getter - protected final Player player; - - public ArmorStandTargetedEvent(ArmorStand armorStand, Player player) { - super(armorStand); - this.player = player; - } - - /* Generated for Bukkit */ - private static final HandlerList handlers = new HandlerList(); - - public static HandlerList getHandlerList() { - return (handlers); - } - - @Override - public HandlerList getHandlers() { - return (handlers); - } -} \ No newline at end of file diff --git a/src/main/java/io/github/rypofalem/armorstandeditor/api/ItemFrameGlowEvent.java b/src/main/java/io/github/rypofalem/armorstandeditor/api/ItemFrameGlowEvent.java deleted file mode 100644 index 7f5cdc97..00000000 --- a/src/main/java/io/github/rypofalem/armorstandeditor/api/ItemFrameGlowEvent.java +++ /dev/null @@ -1,35 +0,0 @@ -package io.github.rypofalem.armorstandeditor.api; - -import lombok.Getter; -import lombok.Setter; - -import org.bukkit.entity.ItemFrame; -import org.bukkit.entity.Player; -import org.bukkit.event.Cancellable; -import org.bukkit.event.HandlerList; - -public class ItemFrameGlowEvent extends ItemFrameEvent implements Cancellable { - @Getter - @Setter - private boolean cancelled = false; - - @Getter - protected final Player player; - - public ItemFrameGlowEvent(ItemFrame itemFrame, Player player) { - super(itemFrame); - this.player = player; - } - - /* Generated for Bukkit */ - private static final HandlerList handlers = new HandlerList(); - - public static HandlerList getHandlerList() { - return (handlers); - } - - @Override - public HandlerList getHandlers() { - return (handlers); - } -} \ No newline at end of file diff --git a/src/main/java/io/github/rypofalem/armorstandeditor/api/ItemFrameManipulatedEvent.java b/src/main/java/io/github/rypofalem/armorstandeditor/api/ItemFrameManipulatedEvent.java deleted file mode 100644 index 9c80c077..00000000 --- a/src/main/java/io/github/rypofalem/armorstandeditor/api/ItemFrameManipulatedEvent.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * ItemFrameEditor: Bukkit plugin to allow editing armor stand attributes - * Copyright (C) 2016-2023 RypoFalem - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package io.github.rypofalem.armorstandeditor.api; - -import lombok.Getter; -import lombok.Setter; - -import org.bukkit.entity.ItemFrame; -import org.bukkit.entity.Player; -import org.bukkit.event.Cancellable; -import org.bukkit.event.HandlerList; - -public class ItemFrameManipulatedEvent extends ItemFrameEvent implements Cancellable { - - @Getter - @Setter - private boolean cancelled = false; - - @Getter - protected final Player player; - - public ItemFrameManipulatedEvent(ItemFrame itemFrame, Player player) { - super(itemFrame); - this.player = player; - } - - /* Generated for Bukkit */ - private static final HandlerList handlers = new HandlerList(); - - public static HandlerList getHandlerList() { - return (handlers); - } - - @Override - public HandlerList getHandlers() { - return (handlers); - } -} - diff --git a/src/main/java/io/github/rypofalem/armorstandeditor/api/ItemFrameTargetedEvent.java b/src/main/java/io/github/rypofalem/armorstandeditor/api/ItemFrameTargetedEvent.java deleted file mode 100644 index 1c9c162c..00000000 --- a/src/main/java/io/github/rypofalem/armorstandeditor/api/ItemFrameTargetedEvent.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * ArmorStandEditor: Bukkit plugin to allow editing armor stand attributes - * Copyright (C) 2016-2023 RypoFalem - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -package io.github.rypofalem.armorstandeditor.api; - -import lombok.Getter; -import lombok.Setter; - -import org.bukkit.entity.ItemFrame; -import org.bukkit.entity.Player; -import org.bukkit.event.Cancellable; -import org.bukkit.event.HandlerList; - -public class ItemFrameTargetedEvent extends ItemFrameEvent implements Cancellable { - @Getter - @Setter - private boolean cancelled = false; - - @Getter - protected final Player player; - - public ItemFrameTargetedEvent(ItemFrame itemFrame, Player player) { - super(itemFrame); - this.player = player; - } - - /* Generated for Bukkit */ - private static final HandlerList handlers = new HandlerList(); - - public static HandlerList getHandlerList() { - return (handlers); - } - - @Override - public HandlerList getHandlers() { - return (handlers); - } -} diff --git a/src/main/java/io/github/rypofalem/armorstandeditor/api/PlayerOpenMenuEvent.java b/src/main/java/io/github/rypofalem/armorstandeditor/api/PlayerOpenMenuEvent.java deleted file mode 100644 index 908b6693..00000000 --- a/src/main/java/io/github/rypofalem/armorstandeditor/api/PlayerOpenMenuEvent.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * ArmorStandEditor: Bukkit plugin to allow editing armor stand attributes - * Copyright (C) 2016-2023 RypoFalem - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package io.github.rypofalem.armorstandeditor.api; - -import lombok.Getter; -import lombok.Setter; - -import org.bukkit.entity.Player; -import org.bukkit.event.Cancellable; -import org.bukkit.event.Event; -import org.bukkit.event.HandlerList; - -public class PlayerOpenMenuEvent extends Event implements Cancellable { - @Getter - @Setter - private boolean cancelled = false; - - @Getter - protected final Player player; - - public PlayerOpenMenuEvent(Player player) { - this.player = player; - } - - /* Generated for Bukkit */ - private static final HandlerList handlers = new HandlerList(); - - public static HandlerList getHandlerList() { - return (handlers); - } - - @Override - public HandlerList getHandlers() { - return (handlers); - } -} \ No newline at end of file From ca51774019179f66e3a275613f36da4924013229 Mon Sep 17 00:00:00 2001 From: Wolfieheart Date: Fri, 3 Jan 2025 23:12:26 +0100 Subject: [PATCH 17/40] [CORE] Bump PaperAPI to latest - End of Day 1 of Rewrite. Signed-off-by: Wolfieheart --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 33405638..3e052eb4 100644 --- a/pom.xml +++ b/pom.xml @@ -46,7 +46,7 @@ io.papermc.paper paper-api - 1.21.1-R0.1-SNAPSHOT + 1.21.4-R0.1-SNAPSHOT provided From 4e2ec5e23b2fba5219672a19997d9591154d7b9b Mon Sep 17 00:00:00 2001 From: Wolfieheart Date: Fri, 3 Jan 2025 23:14:01 +0100 Subject: [PATCH 18/40] [CORE] Remove EditorMenu for now. Fix ASE Holder ;) Signed-off-by: Wolfieheart --- .../github/rypofalem/armorstandeditor/menu/ASEHolder.java | 6 +++++- .../rypofalem/armorstandeditor/menu/EditorMenu.java | 8 -------- 2 files changed, 5 insertions(+), 9 deletions(-) delete mode 100644 src/main/java/io/github/rypofalem/armorstandeditor/menu/EditorMenu.java diff --git a/src/main/java/io/github/rypofalem/armorstandeditor/menu/ASEHolder.java b/src/main/java/io/github/rypofalem/armorstandeditor/menu/ASEHolder.java index 7726732f..f10c64ff 100644 --- a/src/main/java/io/github/rypofalem/armorstandeditor/menu/ASEHolder.java +++ b/src/main/java/io/github/rypofalem/armorstandeditor/menu/ASEHolder.java @@ -3,5 +3,9 @@ import org.bukkit.inventory.InventoryHolder; import org.bukkit.inventory.Inventory; -public interface ASEHolder extends InventoryHolder { +public class ASEHolder implements InventoryHolder { + @Override + public Inventory getInventory() { + return null; + } } diff --git a/src/main/java/io/github/rypofalem/armorstandeditor/menu/EditorMenu.java b/src/main/java/io/github/rypofalem/armorstandeditor/menu/EditorMenu.java deleted file mode 100644 index 69fb452d..00000000 --- a/src/main/java/io/github/rypofalem/armorstandeditor/menu/EditorMenu.java +++ /dev/null @@ -1,8 +0,0 @@ -package io.github.rypofalem.armorstandeditor.menu; - -import org.bukkit.entity.ArmorStand; - -public interface EditorMenu extends ASEHolder{ - void open(); - ArmorStand getArmorStand(); -} From dd4fa45326ac73f97791a925976e56566bb024c3 Mon Sep 17 00:00:00 2001 From: "Larry (Wolfieheart)" Date: Fri, 3 Jan 2025 23:15:40 +0100 Subject: [PATCH 19/40] Update TODO_Rewrite.md --- TODO_Rewrite.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/TODO_Rewrite.md b/TODO_Rewrite.md index 81ce95bf..96d6bcfb 100644 --- a/TODO_Rewrite.md +++ b/TODO_Rewrite.md @@ -4,7 +4,7 @@ ## In Progress - API - Add New APIs for Menu Opening. - - Readd everything there currently. (DONE) + - Readd everything there currently. (CURRENTLY BROKEN. WILL CHECK WITH THE PAPER MC FOLK TOMORROW!) ## TODO: - Menus from 1.21.4-48 @@ -29,4 +29,4 @@ - Debug Output - Langauges - Utils -- Folia Support \ No newline at end of file +- Folia Support From 7ce2b4c123451b2baecc2a8f72d19c2c91132e4c Mon Sep 17 00:00:00 2001 From: Wolfieheart Date: Sat, 4 Jan 2025 11:39:24 +0100 Subject: [PATCH 20/40] [CORE] Move all Abstracts to the Interfaces and see if this implementation for ArmorStandManipulationEvent works? Signed-off-by: Wolfieheart --- .../api/ArmorStandManipulationEvent.java | 48 +++++++++++++++++++ .../api/{ => interfaces}/ArmorStandEvent.java | 2 +- .../api/{ => interfaces}/ItemFrameEvent.java | 2 +- 3 files changed, 50 insertions(+), 2 deletions(-) create mode 100644 src/main/java/io/github/rypofalem/armorstandeditor/api/ArmorStandManipulationEvent.java rename src/main/java/io/github/rypofalem/armorstandeditor/api/{ => interfaces}/ArmorStandEvent.java (94%) rename src/main/java/io/github/rypofalem/armorstandeditor/api/{ => interfaces}/ItemFrameEvent.java (94%) diff --git a/src/main/java/io/github/rypofalem/armorstandeditor/api/ArmorStandManipulationEvent.java b/src/main/java/io/github/rypofalem/armorstandeditor/api/ArmorStandManipulationEvent.java new file mode 100644 index 00000000..bc35b053 --- /dev/null +++ b/src/main/java/io/github/rypofalem/armorstandeditor/api/ArmorStandManipulationEvent.java @@ -0,0 +1,48 @@ +package io.github.rypofalem.armorstandeditor.api; + +import io.github.rypofalem.armorstandeditor.api.interfaces.ArmorStandEvent; +import lombok.Getter; +import lombok.Setter; +import org.bukkit.entity.ArmorStand; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; +import org.jetbrains.annotations.NotNull; + +public class ArmorStandManipulationEvent extends ArmorStandEvent implements Cancellable { + + @Getter + @Setter + private boolean isCancelled = false; + + @Getter + protected final Player player; + + + public ArmorStandManipulationEvent(ArmorStand armorStand, Player player) { + super(armorStand); + this.player = player; + } + + /* Generated for Bukkit */ + private static final HandlerList handlers = new HandlerList(); + + public static HandlerList getHandlerList() { + return (handlers); + } + + @Override + public @NotNull HandlerList getHandlers() { + return handlers; + } + + @Override + public boolean isCancelled() { + return this.isCancelled; + } + + @Override + public void setCancelled(boolean isCancelled) { + this.isCancelled = isCancelled; + } +} diff --git a/src/main/java/io/github/rypofalem/armorstandeditor/api/ArmorStandEvent.java b/src/main/java/io/github/rypofalem/armorstandeditor/api/interfaces/ArmorStandEvent.java similarity index 94% rename from src/main/java/io/github/rypofalem/armorstandeditor/api/ArmorStandEvent.java rename to src/main/java/io/github/rypofalem/armorstandeditor/api/interfaces/ArmorStandEvent.java index e82445c1..28a128da 100644 --- a/src/main/java/io/github/rypofalem/armorstandeditor/api/ArmorStandEvent.java +++ b/src/main/java/io/github/rypofalem/armorstandeditor/api/interfaces/ArmorStandEvent.java @@ -17,7 +17,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -package io.github.rypofalem.armorstandeditor.api; +package io.github.rypofalem.armorstandeditor.api.interfaces; import lombok.Getter; diff --git a/src/main/java/io/github/rypofalem/armorstandeditor/api/ItemFrameEvent.java b/src/main/java/io/github/rypofalem/armorstandeditor/api/interfaces/ItemFrameEvent.java similarity index 94% rename from src/main/java/io/github/rypofalem/armorstandeditor/api/ItemFrameEvent.java rename to src/main/java/io/github/rypofalem/armorstandeditor/api/interfaces/ItemFrameEvent.java index d6358613..61a5502f 100644 --- a/src/main/java/io/github/rypofalem/armorstandeditor/api/ItemFrameEvent.java +++ b/src/main/java/io/github/rypofalem/armorstandeditor/api/interfaces/ItemFrameEvent.java @@ -17,7 +17,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -package io.github.rypofalem.armorstandeditor.api; +package io.github.rypofalem.armorstandeditor.api.interfaces; import lombok.Getter; From 1a576ee8a946d071fb95b5a7c6197379d7676a3a Mon Sep 17 00:00:00 2001 From: Wolfieheart Date: Sat, 4 Jan 2025 11:50:13 +0100 Subject: [PATCH 21/40] [CORE] Reimplement Existing APIs Signed-off-by: Wolfieheart --- .../api/ArmorStandRenameEvent.java | 52 +++++++++++++++++++ .../api/ArmorStandTargettedEvent.java | 48 +++++++++++++++++ .../api/ItemFrameGlowEvent.java | 46 ++++++++++++++++ .../api/ItemFrameManipulationEvent.java | 46 ++++++++++++++++ .../api/ItemFrameTargettedEvent.java | 46 ++++++++++++++++ 5 files changed, 238 insertions(+) create mode 100644 src/main/java/io/github/rypofalem/armorstandeditor/api/ArmorStandRenameEvent.java create mode 100644 src/main/java/io/github/rypofalem/armorstandeditor/api/ArmorStandTargettedEvent.java create mode 100644 src/main/java/io/github/rypofalem/armorstandeditor/api/ItemFrameGlowEvent.java create mode 100644 src/main/java/io/github/rypofalem/armorstandeditor/api/ItemFrameManipulationEvent.java create mode 100644 src/main/java/io/github/rypofalem/armorstandeditor/api/ItemFrameTargettedEvent.java diff --git a/src/main/java/io/github/rypofalem/armorstandeditor/api/ArmorStandRenameEvent.java b/src/main/java/io/github/rypofalem/armorstandeditor/api/ArmorStandRenameEvent.java new file mode 100644 index 00000000..1607e82b --- /dev/null +++ b/src/main/java/io/github/rypofalem/armorstandeditor/api/ArmorStandRenameEvent.java @@ -0,0 +1,52 @@ +package io.github.rypofalem.armorstandeditor.api; + +import io.github.rypofalem.armorstandeditor.api.interfaces.ArmorStandEvent; +import lombok.Getter; +import lombok.Setter; +import org.bukkit.entity.ArmorStand; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; +import org.jetbrains.annotations.NotNull; + +public class ArmorStandRenameEvent extends ArmorStandEvent implements Cancellable { + + + @Getter + @Setter + private boolean isCancelled = false; + @Getter + @Setter + protected String name; + + @Getter + protected final Player player; + + public ArmorStandRenameEvent(ArmorStand armorStand, Player player, String name) { + super(armorStand); + this.player = player; + this.name = name; + } + + /* Generated for Bukkit */ + private static final HandlerList handlers = new HandlerList(); + + public static HandlerList getHandlerList() { + return (handlers); + } + + @Override + public HandlerList getHandlers() { + return (handlers); + } + + @Override + public boolean isCancelled() { + return this.isCancelled; + } + + @Override + public void setCancelled(boolean isCancelled) { + this.isCancelled = isCancelled; + } +} diff --git a/src/main/java/io/github/rypofalem/armorstandeditor/api/ArmorStandTargettedEvent.java b/src/main/java/io/github/rypofalem/armorstandeditor/api/ArmorStandTargettedEvent.java new file mode 100644 index 00000000..4b0bec19 --- /dev/null +++ b/src/main/java/io/github/rypofalem/armorstandeditor/api/ArmorStandTargettedEvent.java @@ -0,0 +1,48 @@ +package io.github.rypofalem.armorstandeditor.api; + +import io.github.rypofalem.armorstandeditor.api.interfaces.ArmorStandEvent; +import lombok.Getter; +import lombok.Setter; +import org.bukkit.entity.ArmorStand; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; +import org.jetbrains.annotations.NotNull; + +public class ArmorStandTargettedEvent extends ArmorStandEvent implements Cancellable { + + @Getter + @Setter + private boolean isCancelled = false; + + @Getter + protected final Player player; + + + public ArmorStandTargettedEvent(ArmorStand armorStand, Player player) { + super(armorStand); + this.player = player; + } + + /* Generated for Bukkit */ + private static final HandlerList handlers = new HandlerList(); + + public static HandlerList getHandlerList() { + return (handlers); + } + + @Override + public @NotNull HandlerList getHandlers() { + return handlers; + } + + @Override + public boolean isCancelled() { + return this.isCancelled; + } + + @Override + public void setCancelled(boolean isCancelled) { + this.isCancelled = isCancelled; + } +} diff --git a/src/main/java/io/github/rypofalem/armorstandeditor/api/ItemFrameGlowEvent.java b/src/main/java/io/github/rypofalem/armorstandeditor/api/ItemFrameGlowEvent.java new file mode 100644 index 00000000..c1ad84c2 --- /dev/null +++ b/src/main/java/io/github/rypofalem/armorstandeditor/api/ItemFrameGlowEvent.java @@ -0,0 +1,46 @@ +package io.github.rypofalem.armorstandeditor.api; + +import io.github.rypofalem.armorstandeditor.api.interfaces.ItemFrameEvent; +import lombok.Getter; +import lombok.Setter; + +import org.bukkit.entity.ItemFrame; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; + +public class ItemFrameGlowEvent extends ItemFrameEvent implements Cancellable { + @Getter + @Setter + private boolean isCancelled = false; + + @Getter + protected final Player player; + + public ItemFrameGlowEvent(ItemFrame itemFrame, Player player) { + super(itemFrame); + this.player = player; + } + + /* Generated for Bukkit */ + private static final HandlerList handlers = new HandlerList(); + + public static HandlerList getHandlerList() { + return (handlers); + } + + @Override + public HandlerList getHandlers() { + return (handlers); + } + + @Override + public boolean isCancelled() { + return this.isCancelled; + } + + @Override + public void setCancelled(boolean isCancelled) { + this.isCancelled = isCancelled; + } +} \ No newline at end of file diff --git a/src/main/java/io/github/rypofalem/armorstandeditor/api/ItemFrameManipulationEvent.java b/src/main/java/io/github/rypofalem/armorstandeditor/api/ItemFrameManipulationEvent.java new file mode 100644 index 00000000..eabee5da --- /dev/null +++ b/src/main/java/io/github/rypofalem/armorstandeditor/api/ItemFrameManipulationEvent.java @@ -0,0 +1,46 @@ +package io.github.rypofalem.armorstandeditor.api; + +import io.github.rypofalem.armorstandeditor.api.interfaces.ItemFrameEvent; +import lombok.Getter; +import lombok.Setter; +import org.bukkit.entity.ItemFrame; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; + +public class ItemFrameManipulationEvent extends ItemFrameEvent implements Cancellable { + + @Getter + @Setter + private boolean isCancelled = false; + + @Getter + protected final Player player; + + public ItemFrameManipulationEvent(ItemFrame itemFrame, Player player) { + super(itemFrame); + this.player = player; + } + + /* Generated for Bukkit */ + private static final HandlerList handlers = new HandlerList(); + + public static HandlerList getHandlerList() { + return (handlers); + } + + @Override + public HandlerList getHandlers() { + return (handlers); + } + + @Override + public boolean isCancelled() { + return this.isCancelled; + } + + @Override + public void setCancelled(boolean isCancelled) { + this.isCancelled = isCancelled; + } +} diff --git a/src/main/java/io/github/rypofalem/armorstandeditor/api/ItemFrameTargettedEvent.java b/src/main/java/io/github/rypofalem/armorstandeditor/api/ItemFrameTargettedEvent.java new file mode 100644 index 00000000..aaa4bad8 --- /dev/null +++ b/src/main/java/io/github/rypofalem/armorstandeditor/api/ItemFrameTargettedEvent.java @@ -0,0 +1,46 @@ +package io.github.rypofalem.armorstandeditor.api; +import io.github.rypofalem.armorstandeditor.api.interfaces.ItemFrameEvent; +import lombok.Getter; +import lombok.Setter; + +import org.bukkit.entity.ItemFrame; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; + +public class ItemFrameTargettedEvent extends ItemFrameEvent implements Cancellable { + @Getter + @Setter + private boolean isCancelled = false; + + @Getter + protected final Player player; + + public ItemFrameTargettedEvent(ItemFrame itemFrame, Player player) { + super(itemFrame); + this.player = player; + } + + /* Generated for Bukkit */ + private static final HandlerList handlers = new HandlerList(); + + public static HandlerList getHandlerList() { + return (handlers); + } + + @Override + public HandlerList getHandlers() { + return (handlers); + } + + @Override + public boolean isCancelled() { + return this.isCancelled; + } + + @Override + public void setCancelled(boolean isCancelled) { + this.isCancelled = isCancelled; + } +} + From 1293d2899fbda0b5032ec5e78b2b1fb186615f17 Mon Sep 17 00:00:00 2001 From: Wolfieheart Date: Sat, 4 Jan 2025 11:56:43 +0100 Subject: [PATCH 22/40] [CORE] Reimplement Language to the Configuration and add English US back Signed-off-by: Wolfieheart --- src/main/resources/config.yml | 7 + src/main/resources/lang/en_US.yml | 374 ++++++++++++++++++++++++++++++ 2 files changed, 381 insertions(+) create mode 100644 src/main/resources/lang/en_US.yml diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index d02fe5d1..1b945386 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -5,6 +5,13 @@ #DO NOT CHANGE THIS - CHANGES AUTOMATICALLY PER UPDATE version: "0.x-Rewrite" +#----------- LANGUAGE +#Name of the language file you wish to use + +#NOTE: If you are editing en_US.yml, it will not persist across restarts due to it being overwritten +#Please read the comments at the top of that file before editing/changing/modifying. +lang: en_US.yml + #----------- WORLD SETTINGS # Enable Per World Support for ArmorStandEditor - Not Enabling this # means it will work for all worlds by default diff --git a/src/main/resources/lang/en_US.yml b/src/main/resources/lang/en_US.yml new file mode 100644 index 00000000..03469657 --- /dev/null +++ b/src/main/resources/lang/en_US.yml @@ -0,0 +1,374 @@ +#This file will be regenerated by the plugin every time the plugin is enabled. +#Do not edit this file. Make a new language file instead. +#Any value not specified in another language file will default to the value listed here. + +#formatting +#A section symbol will be inserted between each character in this section +#http://minecraft.gamepedia.com/Formatting_codes +iconname: 2n +icondescription: 5 +info: 6 +warn: c +menutitle: 8 + +#NOTE from Author: +# Do NOT Add CustomColors to icons (PresetMenu) as it will break how presets work and do the translation + +#info +setmode: + msg: Setting mode to . + head: Head Position + body: Body Position + leftleg: Left Leg Position + rightleg: Right Leg Position + leftarm: Left Arm Position + rightarm: Right Arm Position + equipment: Equipment + showarms: Toggle Show Arms + invisible: Toggle Visibility + size: Toggle Size + disableslots: Toggle Disable Slots + vulnerability: Toggle Vulnerability + gravity: Toggle Gravity + baseplate: Toggle BasePlate + placement: Placement + rotate: Rotate + copy: Copy + paste: Paste + reset: Reset Pose + itemframe: Toggle Itemframe Visibility + playerhead: Get a Players Head +setaxis: + msg: Setting axis to . + x: X + y: Y + z: Z +setslot: + msg: Setting copy slot to . +setadj: + msg: Setting adjustment to . + coarse: Coarse + fine: Fine +setgravity: + msg: Gravity turned . + true: on + false: off +nomode: + msg: Click with the edit tool away from an armorstand to select an editing mode first! +nomodeif: + msg: Click with the Edit Tool away from the ItemFrame to select a mode first! +copied: + msg: ArmorStand state copied to slot . +pasted: + msg: ArmorStand state pasted from slot . +disabledslots: + msg: Toggled Equipment locks +toggleinvulnerability: + msg: ArmorStand vulnerability state has been toggled to . + true: invulnerable + false: vulnerable +target: + msg: ArmorStand target locked. +notarget: + msg: target unlocked. + armorstand: ArmorStand + itemframe: ItemFrame +frametarget: + msg: Itemframe target locked. +give: + msg: Player given Item with CustomModelData +doubletarget: + msg: Please look at either an ArmorStand or an ItemFrame, not both! +nodoubletarget: + msg: Please look at an ArmorStand or an ItemFrame before switching hands! +reloaded: + msg: Configuration File has been reloaded. +playerhead: + msg: Player Head retrieved. +playerheaderror: + msg: Unable to give you a playerhead. +unabledestroycreative: + msg: Unable to Destroy this Invulnerable ArmorStand in Creative Mode. +notincorrectworld: + msg: Sorry but you are not in the correct world to use ArmorStandEditor. +stats: + msg: Here are the statistics for your ArmorStand. +help: + msg: "1. Hold the editing tool() in your main hand + + 2. Left or right click away from an armor stand to open menu. + + 3. Select the labeled menu options. + + 4. Left click the armor stand with the edit tool in hand to apply those options. + + 5. Right click instead to edit in reverse!" +helptips: + msg: "Tips: + + 1. Press the \"Swap Item in Hands\" key (default F) while holding the edit tool to target a specific armor stand, if other armor stands are in the way. + + 2. You can apply NameTags to armor stands. You may use the & symbol to make colored names. + + 3. You can use crouch + scroll wheel while holding the edit tool to change Axis without opening the menu" +helpurl: + msg: "More info: https://github.com/RypoFalem/ArmorStandEditor/wiki" +helpdiscord: + msg: "or join our Discord: https://discord.gg/3BbJKWpTCj" + +#warn +cantedit: + msg: Sorry, you cannot edit armor stands here! +noperm: + msg: You don't have permission to use this! +nopermoption: + msg: You don't have permission to use the Option! + basic: Normal ArmorStand + showarms: Show Arms + armorstandvisibility: Armor Stand Visibility + baseplate: Set Baseplate Visibility + gravity: Toggle Gravity + vulnerability: Toggle Vulnerability + itemframevisibility: Item Frame Visibility + size: Toggle ArmorStand Size + disableslots: Toggle Equipment Lock + paste: Paste ArmorStand Config + copy: Copy ArmorStand Config + reset: Reset ArmorStand Config + stats: View ArmorStand Statistics + armorstandglow: Toggle ArmorStand Glow +norangestats: + msg: Please get next to an ArmorStand before running this command. +noslotnumcom: + msg: You must specify a slot number! +noadjcom: + msg: You must specify Coarse or Fine adjustment! +noaxiscom: + msg: You must specify an Axis! +nomodecom: + msg: You must specify a Mode! +noreloadcom: + msg: You don't have permission to use the reload command! +nogive: + msg: "You either do not have the permission to use the give command or do not allow it in Config.yml" +noconsolecom: + msg: Sorry but this command only works from in-game and not from Console! +renamestopped: + msg: Please make sure you have the ability/permission to give your ArmorStand Colored Names. + +#menutitle +mainmenutitle: + msg: Armor Stand Editor Menu +equiptitle: + msg: ArmorStand Equipment +presettitle: + msg: Pre-Set ArmorStand Poses + +#icons +xaxis: + msg: X Axis + description: + msg: Rotate body parts along the X Axis +yaxis: + msg: Y Axis + description: + msg: Rotate body parts along the Y Axis +zaxis: + msg: Z Axis + description: + msg: Rotate body part s along the Z Axis +coarseadj: + msg: Coarse Adjustment + description: + msg: Make large adjustments +fineadj: + msg: Fine Adjustment + description: + msg: Make tiny adjustments +head: + msg: Head Position + description: + msg: Rotate the head +body: + msg: Body Position + description: + msg: Rotate the body +leftleg: + msg: Left Leg Position + description: + msg: Rotate the left leg +rightleg: + msg: Right Leg Position + description: + msg: Rotate the right leg +leftarm: + msg: Left Arm Position + description: + msg: Rotate the left arm +rightarm: + msg: Right Arm Position + description: + msg: Rotate the right arm +equipment: + msg: Equipment + description: + msg: Edit equipment +showarms: + msg: Show Arms + description: + msg: Turn arms on and off +invisible: + msg: Visibility + description: + msg: Make it visibile or invisible +size: + msg: Size + description: + msg: Make it big or small +disableslots: + msg: Disable Slots + description: + msg: Enable and disable equipment lock +vulnerability: + msg: Toggle Vulnerability + description: + msg: Toggles an ArmorStand's vulnerability state +gravity: + msg: Gravity + description: + msg: Turn gravity on or off +baseplate: + msg: BasePlate + description: + msg: Turn baseplate on or off +placement: + msg: Placement + description: + msg: Move the entire armorstand +rotate: + msg: Rotate + description: + msg: Rotate the entire armorstand +copy: + msg: Copy + description: + msg: Copy the armorstand's settings +paste: + msg: Paste + description: + msg: Paste the armorstand's settings +copyslot: + msg: Copy Slot + description: + msg: Select a slot to store settings +reset: + msg: Reset Pose + description: + msg: Reset bodypart position to default +helpgui: + msg: Help! + description: + msg: Click here to get help! +itemframevisible: + msg: Itemframe Visibility + description: + msg: Toggles an itemframes visibility +playerheadmenu: + msg: Player Head + description: + msg: Click me to get a copy of your own head +blankslot: + msg: Nothing here + description: + msg: Just a placeholder item. Clicking me will not do anything. +armorstandglow: + msg: Toggle ArmorStand Glow + description: + msg: Turn ArmorStand Glowing on or off. + +#icons (equipment menu) +disabled: + msg: Disabled +equipslot: + msg: Slot + description: + msg: Drag your into the slot below + helm: Helmet + chest: Chestplate + pants: Pants + boots: Boots + rhand: Right Hand Item + lhand: Left Hand Item + helm: Helmet + chest: Chestplate + pants: Pants + boots: Feetsies + rhand: Right Hand + lhand: Left Hand + +#all things related to Presets +presetmenu: + msg: Preset Poses + description: + msg: Use a Preset Pose for your ArmorStand [Will Open another Menu] + +#icons (Preset Menu) +sitting: + msg: Sitting + description: + msg: Time to sit back and relax. +waving: + msg: Waving + description: + msg: Hey, Over here! +greeting 1: + msg: Greeting 1 + description: + msg: Greetings, I am your Armor Stand. +greeting 2: + msg: Greeting 2 + description: + msg: Oh Hey there, I am your Armor Stand. +archer: + msg: Archer + description: + msg: Watch out, your Armor Stand is about to shoot you :O +dancing: + msg: Dancing + description: + msg: Hey there, would you like a dance? +cheers: + msg: Cheers + description: + msg: Lets Cheers to this! +hanging: + msg: Hanging + description: + msg: Time to hang onto this mountain like our life depended on it. +present: + msg: Present + description: + msg: Your ArmorStand has a present for you <3 +fishing: + msg: Fishing + description: + msg: Time yo go on a fishing trip + +#Help for Presets +backtomenu: + msg: Back to Menu + description: + msg: Click me to go back to the main menu +howtopreset: + msg: How To + description: + msg: A short message on how to use presets. +howtopresetmsg: + msg: "1. Hold the editing tool in your main hand + + 2. Open the Menu with Preset Mode Active. + + 3. Choose one of the Armor Stand Presets that you want to select. + + 4. After choosing, your menu will close and your chosen preset will be applied. " + From 52eb086350c49d64e43cb1daae8388c57f246308 Mon Sep 17 00:00:00 2001 From: Wolfieheart Date: Sat, 4 Jan 2025 12:35:22 +0100 Subject: [PATCH 23/40] [CORE] Gradle Migration - Better Build System when building against Paper Signed-off-by: Wolfieheart --- .../{maven-publish.yml => gradle-publish.yml} | 42 ++- .gitignore | 25 +- build.gradle | 70 +++++ gradle/libs.versions.toml | 16 ++ gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 43453 bytes gradle/wrapper/gradle-wrapper.properties | 7 + gradlew | 249 ++++++++++++++++++ gradlew.bat | 92 +++++++ pom.xml | 106 -------- settings.gradle | 5 + 10 files changed, 475 insertions(+), 137 deletions(-) rename .github/workflows/{maven-publish.yml => gradle-publish.yml} (52%) create mode 100644 build.gradle create mode 100644 gradle/libs.versions.toml create mode 100644 gradle/wrapper/gradle-wrapper.jar create mode 100644 gradle/wrapper/gradle-wrapper.properties create mode 100644 gradlew create mode 100644 gradlew.bat delete mode 100644 pom.xml create mode 100644 settings.gradle diff --git a/.github/workflows/maven-publish.yml b/.github/workflows/gradle-publish.yml similarity index 52% rename from .github/workflows/maven-publish.yml rename to .github/workflows/gradle-publish.yml index 740674a8..ec1d32db 100644 --- a/.github/workflows/maven-publish.yml +++ b/.github/workflows/gradle-publish.yml @@ -1,7 +1,4 @@ -# This workflow will build a Java project with Maven -# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven - -name: Java CI with Maven +name: Java CI with Gradle on: [push, pull_request] jobs: @@ -25,40 +22,33 @@ jobs: java-version: ${{ matrix.java }} distribution: 'zulu' - # 3. Setup local Maven package cache to speed up building - - name: Cache SonarCloud packages - uses: actions/cache@v3 - with: - path: ~/.sonar/cache - key: ${{ runner.os }}-sonar - restore-keys: ${{ runner.os }}-sonar - - - name: Cache Maven packages + # 3. Setup local Gradle cache to speed up building + - name: Cache Gradle packages uses: actions/cache@v3 with: - path: ~/.m2 - key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} - restore-keys: ${{ runner.os }}-m2 - - # 4. Build via Maven + path: ~/.gradle/caches + key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }} + restore-keys: ${{ runner.os }}-gradle + + # 4. Build and analyze - name: Build and analyze env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed to get PR information, if any SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} - run: mvn -B verify org.sonarsource.scanner.maven:sonar-maven-plugin:sonar -Dsonar.projectKey=wolfieheart_ArmorStandEditor + run: ./gradlew build sonarqube -Dsonar.projectKey=wolfieheart_ArmorStandEditor - #5: Create a Clean Package - and Verify it - - name: Clean package - run: mvn -B clean package + # 5. Create a Clean Package - and Verify it + - name: Clean and build + run: ./gradlew clean build - - name: Clean Verify - run: mvn -B clean verify + - name: Verify build + run: ./gradlew clean test - #6 Upload Artifacts (Debug Purposes) + # 6. Upload Artifacts (Debug Purposes) - name: Upload Artifact for Debugging uses: actions/upload-artifact@v4.0.0 if: success() && matrix.java == '21' with: name: artifact - path: /home/runner/work/ArmorStandEditor/ArmorStandEditor/target/armorstandeditor-*-*.jar + path: build/libs/armorstandeditor-*-*.jar if-no-files-found: error diff --git a/.gitignore b/.gitignore index 9d631327..fe3878bc 100644 --- a/.gitignore +++ b/.gitignore @@ -1,11 +1,26 @@ +# IntelliJ IDEA .idea/ -target/ *.iml + +# Build directories /bin/ -/.project -/.classpath -/.settings/ +/build/ + +# Eclipse IDE +.project +.classpath +.settings/ + +# Java specific metadata /src/main/java/META-INF/*.MF /src/main/java/META-INF/ + +# Project-specific files /TODO-LIST.MD -/dependency-reduced-pom.xml + +# Gradle +.gradle/ +!gradle/wrapper/gradle-wrapper.jar + +# Gradle Wrapper +.gradle-wrapper/ diff --git a/build.gradle b/build.gradle new file mode 100644 index 00000000..0f963efc --- /dev/null +++ b/build.gradle @@ -0,0 +1,70 @@ +plugins { + id 'java' + id 'maven-publish' +} + +group = 'io.github.rypofalem.armorstandeditor' +version = '0.x-Rewrite' + +def javaVersion = 21 + +java { + toolchain { + languageVersion.set(JavaLanguageVersion.of(javaVersion)) + } +} + +tasks.withType(JavaCompile) { + options.encoding = 'UTF-8' +} + +repositories { + mavenCentral() + maven { + url = 'https://repo.papermc.io/repository/maven-public/' + } + maven { + url = 'https://s01.oss.sonatype.org/content/repositories/snapshots/' + } +} + +dependencies { + compileOnly 'io.papermc.paper:paper-api:1.21.4-R0.1-SNAPSHOT' + compileOnly 'org.projectlombok:lombok:1.18.34' + + testImplementation 'org.mockito:mockito-core:5.5.0' + testImplementation 'org.junit.jupiter:junit-jupiter-engine:5.10.0' + testImplementation 'org.junit.jupiter:junit-jupiter-api:5.10.0' +} + +tasks.jar { + manifest { + attributes( + 'Implementation-Title': 'armorstandeditor', + 'Implementation-Version': version + ) + } +} + +tasks.register('attachArtifact') { + doLast { + println "Attach optional artifact if needed." + // Gradle doesn't natively support attaching optional artifacts like Maven. Additional logic might be added here. + } +} + +testing { + suites { + test(JvmTestSuite) { + useJUnitJupiter() + } + } +} + +publishing { + publications { + mavenJava(MavenPublication) { + from components.java + } + } +} diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml new file mode 100644 index 00000000..1e250ab8 --- /dev/null +++ b/gradle/libs.versions.toml @@ -0,0 +1,16 @@ +# This file was generated by the Gradle 'init' task. +# https://docs.gradle.org/current/userguide/platforms.html#sub::toml-dependencies-format + +[versions] +io-papermc-paper-paper-api = "1.21.4-R0.1-SNAPSHOT" +org-junit-jupiter-junit-jupiter-api = "5.10.0" +org-junit-jupiter-junit-jupiter-engine = "5.10.0" +org-mockito-mockito-core = "5.5.0" +org-projectlombok-lombok = "1.18.34" + +[libraries] +io-papermc-paper-paper-api = { module = "io.papermc.paper:paper-api", version.ref = "io-papermc-paper-paper-api" } +org-junit-jupiter-junit-jupiter-api = { module = "org.junit.jupiter:junit-jupiter-api", version.ref = "org-junit-jupiter-junit-jupiter-api" } +org-junit-jupiter-junit-jupiter-engine = { module = "org.junit.jupiter:junit-jupiter-engine", version.ref = "org-junit-jupiter-junit-jupiter-engine" } +org-mockito-mockito-core = { module = "org.mockito:mockito-core", version.ref = "org-mockito-mockito-core" } +org-projectlombok-lombok = { module = "org.projectlombok:lombok", version.ref = "org-projectlombok-lombok" } diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..e6441136f3d4ba8a0da8d277868979cfbc8ad796 GIT binary patch literal 43453 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 yu?e%!_ptzGB|8GrCfu%p?(_ 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
NnX)EH+Nua)3Y(c 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 '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 00000000..25da30db --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,92 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/pom.xml b/pom.xml deleted file mode 100644 index 3e052eb4..00000000 --- a/pom.xml +++ /dev/null @@ -1,106 +0,0 @@ - - 4.0.0 - io.github.rypofalem.armorstandeditor - armorstandeditor - jar - 0.x-Rewrite - armorstandeditor - https://maven.apache.org - - - 21 - UTF-8 - 3.1.1 - wolfieheart - https://sonarcloud.io - - - - - Wolfieheart - Wolfieheart - https://github.com/Wolfieheart - - - RypoFalem - RypoFalem - https://github.com/RypoFalem - - - - - - - paper-repo - https://repo.papermc.io/repository/maven-public/ - - - sonatype-oss-snapshots1 - https://s01.oss.sonatype.org/content/repositories/snapshots/ - - - - - - - io.papermc.paper - paper-api - 1.21.4-R0.1-SNAPSHOT - provided - - - - org.projectlombok - lombok - 1.18.34 - provided - - - - - - - org.codehaus.mojo - build-helper-maven-plugin - 3.5.0 - - - compile - package - - attach-artifact - - - - - ${project.build.directory}/${project.artifactId}.jar - jar - optional - - - - - - - - org.apache.maven.plugins - maven-compiler-plugin - 3.13.0 - - ${java.version} - ${java.version} - - - - org.apache.maven.plugins - maven-release-plugin - ${maven-release-plugin.version} - - [ci skip] || [CI SKIP] || [CI-SKIP] - @{project.version} - - - - - diff --git a/settings.gradle b/settings.gradle new file mode 100644 index 00000000..7c16d16d --- /dev/null +++ b/settings.gradle @@ -0,0 +1,5 @@ +/* + * This file was generated by the Gradle 'init' task. + */ + +rootProject.name = 'armorstandeditor' From 73f527d5d6da9539c5a56757277f8aa4b3aeb198 Mon Sep 17 00:00:00 2001 From: Wolfieheart Date: Sat, 4 Jan 2025 12:37:27 +0100 Subject: [PATCH 24/40] [CORE] Gradle Migration - Fix Build Pipeline Signed-off-by: Wolfieheart --- .github/workflows/gradle-publish.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/gradle-publish.yml b/.github/workflows/gradle-publish.yml index ec1d32db..e2d61009 100644 --- a/.github/workflows/gradle-publish.yml +++ b/.github/workflows/gradle-publish.yml @@ -30,6 +30,9 @@ jobs: key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }} restore-keys: ${{ runner.os }}-gradle + - name: Grant execute permission for Gradle Wrapper + run: chmod +x ./gradlew + # 4. Build and analyze - name: Build and analyze env: From 50c8e17523bdac8d523ca7aea978006d57ec52a7 Mon Sep 17 00:00:00 2001 From: Wolfieheart Date: Sat, 4 Jan 2025 12:39:23 +0100 Subject: [PATCH 25/40] [CORE] Gradle Migration - Upgrade to 8.12 Signed-off-by: Wolfieheart --- gradle/wrapper/gradle-wrapper.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index b82aa23a..cea7a793 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME From 75c97bc56ada7c8487e39cdafaeb85299eaa987f Mon Sep 17 00:00:00 2001 From: Wolfieheart Date: Sat, 4 Jan 2025 12:43:42 +0100 Subject: [PATCH 26/40] [CORE] Gradle Migration - Add Sonarqube into the mix Signed-off-by: Wolfieheart --- .github/workflows/gradle-publish.yml | 4 ++-- build.gradle | 10 ++++++++++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/.github/workflows/gradle-publish.yml b/.github/workflows/gradle-publish.yml index e2d61009..666ee506 100644 --- a/.github/workflows/gradle-publish.yml +++ b/.github/workflows/gradle-publish.yml @@ -36,9 +36,9 @@ jobs: # 4. Build and analyze - name: Build and analyze env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed to get PR information, if any + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} - run: ./gradlew build sonarqube -Dsonar.projectKey=wolfieheart_ArmorStandEditor + run: ./gradlew build sonarqube -Dsonar.projectKey=wolfieheart_ArmorStandEditor || echo "Skipping SonarQube analysis" # 5. Create a Clean Package - and Verify it - name: Clean and build diff --git a/build.gradle b/build.gradle index 0f963efc..e7a95b80 100644 --- a/build.gradle +++ b/build.gradle @@ -1,6 +1,7 @@ plugins { id 'java' id 'maven-publish' + id 'org.sonarqube' version '10.6' } group = 'io.github.rypofalem.armorstandeditor' @@ -14,6 +15,15 @@ java { } } +sonarqube { + properties { + property "sonar.projectKey", "wolfieheart_ArmorStandEditor" + property "sonar.organization", "wolfieheart" + property "sonar.host.url", "https://sonarcloud.io" + property "sonar.login", System.getenv("SONAR_TOKEN") + } +} + tasks.withType(JavaCompile) { options.encoding = 'UTF-8' } From 45949d1055706f2de62da6b3abf367e88dd91e57 Mon Sep 17 00:00:00 2001 From: Wolfieheart Date: Sat, 4 Jan 2025 12:51:07 +0100 Subject: [PATCH 27/40] [CORE] Gradle Migration - Wrong Sonarqube Build.... Signed-off-by: Wolfieheart --- build.gradle | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/build.gradle b/build.gradle index e7a95b80..f34ee4e8 100644 --- a/build.gradle +++ b/build.gradle @@ -1,7 +1,7 @@ plugins { id 'java' id 'maven-publish' - id 'org.sonarqube' version '10.6' + id 'org.sonarqube' version '6.0.1.5171' } group = 'io.github.rypofalem.armorstandeditor' @@ -15,12 +15,12 @@ java { } } -sonarqube { +sonar { properties { property "sonar.projectKey", "wolfieheart_ArmorStandEditor" property "sonar.organization", "wolfieheart" property "sonar.host.url", "https://sonarcloud.io" - property "sonar.login", System.getenv("SONAR_TOKEN") + property "sonar.token", System.getenv("SONAR_TOKEN") } } From 4a40c109cc4d462ff56473cc2c7bcfe51278188f Mon Sep 17 00:00:00 2001 From: Wolfieheart Date: Sat, 4 Jan 2025 13:07:47 +0100 Subject: [PATCH 28/40] [CORE] Gradle Migration - Debug Artifact Dump Signed-off-by: Wolfieheart --- .github/workflows/gradle-publish.yml | 8 +++++++- .gitignore | 4 +++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/.github/workflows/gradle-publish.yml b/.github/workflows/gradle-publish.yml index 666ee506..35a4715f 100644 --- a/.github/workflows/gradle-publish.yml +++ b/.github/workflows/gradle-publish.yml @@ -47,11 +47,17 @@ jobs: - name: Verify build run: ./gradlew clean test + + # 6. Upload Artifacts (Debug Purposes) + - name: List files in build/libs + run: ls -l build/libs + - name: Upload Artifact for Debugging uses: actions/upload-artifact@v4.0.0 if: success() && matrix.java == '21' with: name: artifact - path: build/libs/armorstandeditor-*-*.jar + path: build/libs/armorstandeditor-*.jar if-no-files-found: error + diff --git a/.gitignore b/.gitignore index fe3878bc..74b090a6 100644 --- a/.gitignore +++ b/.gitignore @@ -4,7 +4,9 @@ # Build directories /bin/ -/build/ +**/build +dist/ + # Eclipse IDE .project From d080b9ca416f1c02d1cf545cb97a1ccd7af22803 Mon Sep 17 00:00:00 2001 From: Wolfieheart Date: Sat, 4 Jan 2025 13:09:35 +0100 Subject: [PATCH 29/40] [CORE] Gradle Migration - Debug Artifact Dump Signed-off-by: Wolfieheart --- .github/workflows/gradle-publish.yml | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/.github/workflows/gradle-publish.yml b/.github/workflows/gradle-publish.yml index 35a4715f..52538a77 100644 --- a/.github/workflows/gradle-publish.yml +++ b/.github/workflows/gradle-publish.yml @@ -38,7 +38,7 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} - run: ./gradlew build sonarqube -Dsonar.projectKey=wolfieheart_ArmorStandEditor || echo "Skipping SonarQube analysis" + run: ./gradlew build sonar -Dsonar.projectKey=wolfieheart_ArmorStandEditor || echo "Skipping SonarQube analysis" # 5. Create a Clean Package - and Verify it - name: Clean and build @@ -47,17 +47,15 @@ jobs: - name: Verify build run: ./gradlew clean test - - # 6. Upload Artifacts (Debug Purposes) - name: List files in build/libs - run: ls -l build/libs + run: ls -l /home/runner/work/ArmorStandEditor/ArmorStandEditor/build/libs - name: Upload Artifact for Debugging uses: actions/upload-artifact@v4.0.0 if: success() && matrix.java == '21' with: name: artifact - path: build/libs/armorstandeditor-*.jar + path: /home/runner/work/ArmorStandEditor/ArmorStandEditor/build/libs/armorstandeditor-*.jar if-no-files-found: error From 115d47f749d14a5407bc66d86f71dc2fe3a73d41 Mon Sep 17 00:00:00 2001 From: Wolfieheart Date: Sat, 4 Jan 2025 13:12:12 +0100 Subject: [PATCH 30/40] [CORE] Gradle Migration - Debug Artifact Dump Signed-off-by: Wolfieheart --- .github/workflows/gradle-publish.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/gradle-publish.yml b/.github/workflows/gradle-publish.yml index 52538a77..e0f0ed52 100644 --- a/.github/workflows/gradle-publish.yml +++ b/.github/workflows/gradle-publish.yml @@ -44,13 +44,13 @@ jobs: - name: Clean and build run: ./gradlew clean build + - name: List files in build/libs + run: ls -l /home/runner/work/ArmorStandEditor/build/libs + - name: Verify build run: ./gradlew clean test # 6. Upload Artifacts (Debug Purposes) - - name: List files in build/libs - run: ls -l /home/runner/work/ArmorStandEditor/ArmorStandEditor/build/libs - - name: Upload Artifact for Debugging uses: actions/upload-artifact@v4.0.0 if: success() && matrix.java == '21' From 1742a880c28066fbbec93c0f155b4e08d715761b Mon Sep 17 00:00:00 2001 From: Wolfieheart Date: Sat, 4 Jan 2025 13:15:44 +0100 Subject: [PATCH 31/40] [CORE] Gradle Migration - Debug Artifact Dump Signed-off-by: Wolfieheart --- .github/workflows/gradle-publish.yml | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/.github/workflows/gradle-publish.yml b/.github/workflows/gradle-publish.yml index e0f0ed52..04c4555a 100644 --- a/.github/workflows/gradle-publish.yml +++ b/.github/workflows/gradle-publish.yml @@ -42,13 +42,10 @@ jobs: # 5. Create a Clean Package - and Verify it - name: Clean and build - run: ./gradlew clean build + run: ./gradlew clean build --info - - name: List files in build/libs - run: ls -l /home/runner/work/ArmorStandEditor/build/libs - - - name: Verify build - run: ./gradlew clean test + - name: List files in build dir + run: ls -lR /home/runner/work/ArmorStandEditor/ArmorStandEditor/build/ # 6. Upload Artifacts (Debug Purposes) - name: Upload Artifact for Debugging From 9612326a9100d3ce2378e1be66a5878553181c26 Mon Sep 17 00:00:00 2001 From: Wolfieheart Date: Sat, 4 Jan 2025 13:17:51 +0100 Subject: [PATCH 32/40] [CORE] Gradle Migration - Remove Debug from Pipeline Signed-off-by: Wolfieheart --- .github/workflows/gradle-publish.yml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/.github/workflows/gradle-publish.yml b/.github/workflows/gradle-publish.yml index 04c4555a..4a359f04 100644 --- a/.github/workflows/gradle-publish.yml +++ b/.github/workflows/gradle-publish.yml @@ -42,10 +42,7 @@ jobs: # 5. Create a Clean Package - and Verify it - name: Clean and build - run: ./gradlew clean build --info - - - name: List files in build dir - run: ls -lR /home/runner/work/ArmorStandEditor/ArmorStandEditor/build/ + run: ./gradlew clean build # 6. Upload Artifacts (Debug Purposes) - name: Upload Artifact for Debugging From bba9c79836b0147442e8cf8573d5e71d100f98f7 Mon Sep 17 00:00:00 2001 From: Wolfieheart Date: Sat, 4 Jan 2025 13:21:10 +0100 Subject: [PATCH 33/40] [CORE] CI - Upgrade from ubuntu-latest to 24.04 (See actions#10636 for more information) Signed-off-by: Wolfieheart --- .github/workflows/gradle-publish.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/gradle-publish.yml b/.github/workflows/gradle-publish.yml index 4a359f04..ea967bbf 100644 --- a/.github/workflows/gradle-publish.yml +++ b/.github/workflows/gradle-publish.yml @@ -4,7 +4,7 @@ on: [push, pull_request] jobs: compile: if: "!contains(github.event.head_commit.message, 'ci-skip') || !contains(github.event.head_commit.message, 'CI-SKIP') || !contains(github.event.head_commit.message, 'CI SKIP') || !contains(github.event.head_commit.message, 'ci skip') " - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 strategy: matrix: java: ['21', '23'] From 0ee2d4381ed27158f888d70b271597518f91d739 Mon Sep 17 00:00:00 2001 From: Wolfieheart Date: Sat, 4 Jan 2025 13:34:49 +0100 Subject: [PATCH 34/40] [CORE] Re-implement Modes Signed-off-by: Wolfieheart --- .../modes/AdjustmentMode.java | 34 ++++++++++++ .../modes/ArmorStandData.java | 52 +++++++++++++++++++ .../armorstandeditor/modes/Axis.java | 34 ++++++++++++ .../armorstandeditor/modes/CopySlots.java | 29 +++++++++++ .../armorstandeditor/modes/EditMode.java | 19 +++++++ 5 files changed, 168 insertions(+) create mode 100644 src/main/java/io/github/rypofalem/armorstandeditor/modes/AdjustmentMode.java create mode 100644 src/main/java/io/github/rypofalem/armorstandeditor/modes/ArmorStandData.java create mode 100644 src/main/java/io/github/rypofalem/armorstandeditor/modes/Axis.java create mode 100644 src/main/java/io/github/rypofalem/armorstandeditor/modes/CopySlots.java create mode 100644 src/main/java/io/github/rypofalem/armorstandeditor/modes/EditMode.java diff --git a/src/main/java/io/github/rypofalem/armorstandeditor/modes/AdjustmentMode.java b/src/main/java/io/github/rypofalem/armorstandeditor/modes/AdjustmentMode.java new file mode 100644 index 00000000..0e0f1386 --- /dev/null +++ b/src/main/java/io/github/rypofalem/armorstandeditor/modes/AdjustmentMode.java @@ -0,0 +1,34 @@ +/* + * ArmorStandEditor: Bukkit plugin to allow editing armor stand attributes + * Copyright (C) 2016-2023 RypoFalem + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +package io.github.rypofalem.armorstandeditor.modes; + +public enum AdjustmentMode { + COARSE("Coarse"), FINE("Fine"); + + private String name; + + AdjustmentMode(String name) { + this.name = name; + } + + public String toString() { + return name; + } +} diff --git a/src/main/java/io/github/rypofalem/armorstandeditor/modes/ArmorStandData.java b/src/main/java/io/github/rypofalem/armorstandeditor/modes/ArmorStandData.java new file mode 100644 index 00000000..7f906422 --- /dev/null +++ b/src/main/java/io/github/rypofalem/armorstandeditor/modes/ArmorStandData.java @@ -0,0 +1,52 @@ +/* + * ArmorStandEditor: Bukkit plugin to allow editing armor stand attributes + * Copyright (C) 2016-2023 RypoFalem + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +package io.github.rypofalem.armorstandeditor.modes; + +import org.bukkit.entity.ArmorStand; +import org.bukkit.inventory.ItemStack; +import org.bukkit.util.EulerAngle; + +public class ArmorStandData { + public EulerAngle headPos, leftArmPos, rightArmPos, bodyPos, leftLegPos, rightLegPos; + public boolean visible, size, basePlate, gravity, showArms; + public ItemStack head, body, legs, feetsies, rightHand, leftHand; + + ArmorStandData(ArmorStand as) { + this.headPos = as.getHeadPose(); + this.leftArmPos = as.getLeftArmPose(); + this.rightArmPos = as.getRightArmPose(); + this.bodyPos = as.getBodyPose(); + this.leftLegPos = as.getLeftLegPose(); + this.rightLegPos = as.getRightLegPose(); + this.size = as.isSmall(); + this.basePlate = as.hasBasePlate(); + this.gravity = as.hasGravity(); + this.showArms = as.hasArms(); + this.visible = as.isVisible(); + + //Fix for Depreciate Armor Stand STuff + this.head = as.getEquipment().getHelmet(); + this.body = as.getEquipment().getChestplate(); + this.legs = as.getEquipment().getLeggings(); + this.feetsies = as.getEquipment().getBoots(); + this.rightHand = as.getEquipment().getItemInMainHand(); + this.leftHand = as.getEquipment().getItemInOffHand(); + } +} diff --git a/src/main/java/io/github/rypofalem/armorstandeditor/modes/Axis.java b/src/main/java/io/github/rypofalem/armorstandeditor/modes/Axis.java new file mode 100644 index 00000000..afa6c45c --- /dev/null +++ b/src/main/java/io/github/rypofalem/armorstandeditor/modes/Axis.java @@ -0,0 +1,34 @@ +/* + * ArmorStandEditor: Bukkit plugin to allow editing armor stand attributes + * Copyright (C) 2016-2023 RypoFalem + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +package io.github.rypofalem.armorstandeditor.modes; + +public enum Axis { + X("X"),Y("Y"),Z("Z"); + + String name; + + Axis(String name) { + this.name = name; + } + + public String toString() { + return name; + } +} diff --git a/src/main/java/io/github/rypofalem/armorstandeditor/modes/CopySlots.java b/src/main/java/io/github/rypofalem/armorstandeditor/modes/CopySlots.java new file mode 100644 index 00000000..c505b2b7 --- /dev/null +++ b/src/main/java/io/github/rypofalem/armorstandeditor/modes/CopySlots.java @@ -0,0 +1,29 @@ +package io.github.rypofalem.armorstandeditor.modes; + +import lombok.Getter; +import org.bukkit.entity.ArmorStand; + +@Getter +public class CopySlots { + ArmorStandData[] slots = new ArmorStandData[9]; + public byte currentSlot = 0; + + //returns true if parameters are acceptable, false otherwise. + public boolean changeSlots(byte slot) { + if (slot < slots.length && slot >= 0) { + currentSlot = slot; + return true; + } else { + return false; + } + } + + public void copyDataToSlot(ArmorStand armorStand) { + slots[currentSlot] = new ArmorStandData(armorStand); + } + + //returns null if there is not data in current slot + public ArmorStandData getDataToPaste() { + return slots[currentSlot]; + } +} diff --git a/src/main/java/io/github/rypofalem/armorstandeditor/modes/EditMode.java b/src/main/java/io/github/rypofalem/armorstandeditor/modes/EditMode.java new file mode 100644 index 00000000..90a8fd90 --- /dev/null +++ b/src/main/java/io/github/rypofalem/armorstandeditor/modes/EditMode.java @@ -0,0 +1,19 @@ +package io.github.rypofalem.armorstandeditor.modes; + +public enum EditMode { + NONE("None"), INVISIBLE("Invisible"), SHOWARMS("ShowArms"), GRAVITY("Gravity"), BASEPLATE("BasePlate"), SIZE("Size"), + COPY("Copy"), PASTE("Paste"), HEAD("Head"), BODY("Body"), LEFTARM("LeftArm"), RIGHTARM("RightArm"), LEFTLEG("LeftLeg"), + RIGHTLEG("RightLeg"), PLACEMENT("Placement"), DISABLESLOTS("DisableSlots"), ROTATE("Rotate"), EQUIPMENT("Equipment"), PRESET("Preset"), + RESET("Reset"), ITEMFRAME("ItemFrame"), ITEMFRAMEGLOW("ItemFrameGlow"), VULNERABILITY("Vulnerability"), PLAYERHEAD("playerheadmenu"), + GLOWING("armorstandglow"); + + private String name; + + EditMode(String name) { + this.name = name; + } + + public String toString() { + return name; + } +} From 2dc072e2db57fded23cd16484e8df98b55fef68a Mon Sep 17 00:00:00 2001 From: Wolfieheart Date: Sat, 4 Jan 2025 13:37:27 +0100 Subject: [PATCH 35/40] [CORE] Modes - Formatting Fixes Signed-off-by: Wolfieheart --- .../modes/AdjustmentMode.java | 3 +- .../modes/ArmorStandData.java | 20 +++++++++++-- .../armorstandeditor/modes/Axis.java | 4 ++- .../armorstandeditor/modes/EditMode.java | 28 ++++++++++++++++--- 4 files changed, 46 insertions(+), 9 deletions(-) diff --git a/src/main/java/io/github/rypofalem/armorstandeditor/modes/AdjustmentMode.java b/src/main/java/io/github/rypofalem/armorstandeditor/modes/AdjustmentMode.java index 0e0f1386..55087e33 100644 --- a/src/main/java/io/github/rypofalem/armorstandeditor/modes/AdjustmentMode.java +++ b/src/main/java/io/github/rypofalem/armorstandeditor/modes/AdjustmentMode.java @@ -20,7 +20,8 @@ package io.github.rypofalem.armorstandeditor.modes; public enum AdjustmentMode { - COARSE("Coarse"), FINE("Fine"); + COARSE("Coarse"), + FINE("Fine"); private String name; diff --git a/src/main/java/io/github/rypofalem/armorstandeditor/modes/ArmorStandData.java b/src/main/java/io/github/rypofalem/armorstandeditor/modes/ArmorStandData.java index 7f906422..9962b6eb 100644 --- a/src/main/java/io/github/rypofalem/armorstandeditor/modes/ArmorStandData.java +++ b/src/main/java/io/github/rypofalem/armorstandeditor/modes/ArmorStandData.java @@ -24,9 +24,23 @@ import org.bukkit.util.EulerAngle; public class ArmorStandData { - public EulerAngle headPos, leftArmPos, rightArmPos, bodyPos, leftLegPos, rightLegPos; - public boolean visible, size, basePlate, gravity, showArms; - public ItemStack head, body, legs, feetsies, rightHand, leftHand; + public EulerAngle headPos; + public EulerAngle leftArmPos; + public EulerAngle rightArmPos; + public EulerAngle bodyPos; + public EulerAngle leftLegPos; + public EulerAngle rightLegPos; + public boolean visible; + public boolean size; + public boolean basePlate; + public boolean gravity; + public boolean showArms; + public ItemStack head; + public ItemStack body; + public ItemStack legs; + public ItemStack feetsies; + public ItemStack rightHand; + public ItemStack leftHand; ArmorStandData(ArmorStand as) { this.headPos = as.getHeadPose(); diff --git a/src/main/java/io/github/rypofalem/armorstandeditor/modes/Axis.java b/src/main/java/io/github/rypofalem/armorstandeditor/modes/Axis.java index afa6c45c..fb366729 100644 --- a/src/main/java/io/github/rypofalem/armorstandeditor/modes/Axis.java +++ b/src/main/java/io/github/rypofalem/armorstandeditor/modes/Axis.java @@ -20,7 +20,9 @@ package io.github.rypofalem.armorstandeditor.modes; public enum Axis { - X("X"),Y("Y"),Z("Z"); + X("X"), + Y("Y"), + Z("Z"); String name; diff --git a/src/main/java/io/github/rypofalem/armorstandeditor/modes/EditMode.java b/src/main/java/io/github/rypofalem/armorstandeditor/modes/EditMode.java index 90a8fd90..033bb897 100644 --- a/src/main/java/io/github/rypofalem/armorstandeditor/modes/EditMode.java +++ b/src/main/java/io/github/rypofalem/armorstandeditor/modes/EditMode.java @@ -1,10 +1,30 @@ package io.github.rypofalem.armorstandeditor.modes; public enum EditMode { - NONE("None"), INVISIBLE("Invisible"), SHOWARMS("ShowArms"), GRAVITY("Gravity"), BASEPLATE("BasePlate"), SIZE("Size"), - COPY("Copy"), PASTE("Paste"), HEAD("Head"), BODY("Body"), LEFTARM("LeftArm"), RIGHTARM("RightArm"), LEFTLEG("LeftLeg"), - RIGHTLEG("RightLeg"), PLACEMENT("Placement"), DISABLESLOTS("DisableSlots"), ROTATE("Rotate"), EQUIPMENT("Equipment"), PRESET("Preset"), - RESET("Reset"), ITEMFRAME("ItemFrame"), ITEMFRAMEGLOW("ItemFrameGlow"), VULNERABILITY("Vulnerability"), PLAYERHEAD("playerheadmenu"), + NONE("None"), + INVISIBLE("Invisible"), + SHOWARMS("ShowArms"), + GRAVITY("Gravity"), + BASEPLATE("BasePlate"), + SIZE("Size"), + COPY("Copy"), + PASTE("Paste"), + HEAD("Head"), + BODY("Body"), + LEFTARM("LeftArm"), + RIGHTARM("RightArm"), + LEFTLEG("LeftLeg"), + RIGHTLEG("RightLeg"), + PLACEMENT("Placement"), + DISABLESLOTS("DisableSlots"), + ROTATE("Rotate"), + EQUIPMENT("Equipment"), + PRESET("Preset"), + RESET("Reset"), + ITEMFRAME("ItemFrame"), + ITEMFRAMEGLOW("ItemFrameGlow"), + VULNERABILITY("Vulnerability"), + PLAYERHEAD("playerheadmenu"), GLOWING("armorstandglow"); private String name; From 3c6fa6ef5f5185795dc93439d678acf7bb4a9957 Mon Sep 17 00:00:00 2001 From: Wolfieheart Date: Sat, 4 Jan 2025 13:39:00 +0100 Subject: [PATCH 36/40] [CI-SKIP] Update TODO_Rewrite.md Signed-off-by: Wolfieheart --- TODO_Rewrite.md | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/TODO_Rewrite.md b/TODO_Rewrite.md index 96d6bcfb..299251a6 100644 --- a/TODO_Rewrite.md +++ b/TODO_Rewrite.md @@ -4,8 +4,8 @@ ## In Progress - API - Add New APIs for Menu Opening. - - Readd everything there currently. (CURRENTLY BROKEN. WILL CHECK WITH THE PAPER MC FOLK TOMORROW!) - +- Player Editor Reimplementation + ## TODO: - Menus from 1.21.4-48 - Sizing Rework @@ -14,11 +14,10 @@ - Equipment - Player Editor Reimplementation - Start with Menu Critical things -- Modes - Commands - Permissions - - Protections +- Testing for Config Options in the Code ## Done @@ -30,3 +29,7 @@ - Langauges - Utils - Folia Support +- Modes +- API + - Readd everything there currently. +- Gradle Migration \ No newline at end of file From c2b285539ba6e8d2fb62ba54c01fa63ec9dc6552 Mon Sep 17 00:00:00 2001 From: Wolfieheart Date: Sat, 4 Jan 2025 13:46:58 +0100 Subject: [PATCH 37/40] [CORE] Ground Work for PlayerEditor and PlayerEditorManager. Make sure that MetricsHandler uses the ASE Instance. Signed-off-by: Wolfieheart --- .../ArmorStandEditorPlugin.java | 4 +- .../armorstandeditor/PlayerEditor.java | 50 +++++++++++++++++++ .../armorstandeditor/PlayerEditorManager.java | 43 ++++++++++++++++ .../metricshandler/MetricsHandler.java | 3 +- 4 files changed, 98 insertions(+), 2 deletions(-) create mode 100644 src/main/java/io/github/rypofalem/armorstandeditor/PlayerEditor.java create mode 100644 src/main/java/io/github/rypofalem/armorstandeditor/PlayerEditorManager.java diff --git a/src/main/java/io/github/rypofalem/armorstandeditor/ArmorStandEditorPlugin.java b/src/main/java/io/github/rypofalem/armorstandeditor/ArmorStandEditorPlugin.java index c23e17b7..e7a860b4 100644 --- a/src/main/java/io/github/rypofalem/armorstandeditor/ArmorStandEditorPlugin.java +++ b/src/main/java/io/github/rypofalem/armorstandeditor/ArmorStandEditorPlugin.java @@ -25,6 +25,7 @@ public final class ArmorStandEditorPlugin extends JavaPlugin { private static ArmorStandEditorPlugin instance; private Debug debug = new Debug(this); MetricsHandler metricsHandler; + protected PlayerEditorManager editorManager; // Server Software Check True/False boolean isFolia; @@ -145,7 +146,8 @@ public void onEnable() { getLogger().log(Level.INFO, SEPARATOR_FIELD); // Do all the Metrics for BStats - metricsHandler = new MetricsHandler(); + metricsHandler = new MetricsHandler(this); + editorManager = new PlayerEditorManager(this); } diff --git a/src/main/java/io/github/rypofalem/armorstandeditor/PlayerEditor.java b/src/main/java/io/github/rypofalem/armorstandeditor/PlayerEditor.java new file mode 100644 index 00000000..9dd54ae8 --- /dev/null +++ b/src/main/java/io/github/rypofalem/armorstandeditor/PlayerEditor.java @@ -0,0 +1,50 @@ +package io.github.rypofalem.armorstandeditor; + +import io.github.rypofalem.armorstandeditor.devtools.Debug; +import io.github.rypofalem.armorstandeditor.modes.AdjustmentMode; +import io.github.rypofalem.armorstandeditor.modes.Axis; +import io.github.rypofalem.armorstandeditor.modes.CopySlots; +import io.github.rypofalem.armorstandeditor.modes.EditMode; +import lombok.Getter; +import org.bukkit.entity.ArmorStand; +import org.bukkit.entity.Player; + +import java.util.ArrayList; +import java.util.UUID; + +public class PlayerEditor { + public ArmorStandEditorPlugin plugin; + private Debug debug; + private UUID uuid; + private long lastOpened = Integer.MIN_VALUE; + + @Getter EditMode eMode; + @Getter AdjustmentMode adjMode; + CopySlots copySlots; + @Getter Axis axis; + double eulerAngleChange; + double degreeAngleChange; + double movChange; + //TODO: Add Menu Here once that is reimplemented + ArmorStand targeted; + ArrayList targetList = null; + int targetIndex = 0; + long lastCancelled = 0; + + public PlayerEditor(UUID uuid, ArmorStandEditorPlugin plugin){ + this.uuid = uuid; + this.plugin = plugin; + eMode = EditMode.NONE; + adjMode = AdjustmentMode.COARSE; + axis = Axis.X; + copySlots = new CopySlots(); + eulerAngleChange = getManager().coarseAdj; + degreeAngleChange = eulerAngleChange / Math.PI * 180; + movChange = getManager().coarseMov; + } + + public PlayerEditorManager getManager() { + return plugin.editorManager; + } + +} diff --git a/src/main/java/io/github/rypofalem/armorstandeditor/PlayerEditorManager.java b/src/main/java/io/github/rypofalem/armorstandeditor/PlayerEditorManager.java new file mode 100644 index 00000000..e1c9aee9 --- /dev/null +++ b/src/main/java/io/github/rypofalem/armorstandeditor/PlayerEditorManager.java @@ -0,0 +1,43 @@ +package io.github.rypofalem.armorstandeditor; + +import org.bukkit.Bukkit; +import org.bukkit.event.Listener; +import io.github.rypofalem.armorstandeditor.util.Util; + +import java.util.HashMap; +import java.util.UUID; + +public class PlayerEditorManager implements Listener { + private ArmorStandEditorPlugin plugin; + private HashMap players; + double coarseAdj; + double fineAdj; + double coarseMov; + double fineMov; + private boolean ignoreNextInteract = false; + private TickCounter counter; + + PlayerEditorManager(final ArmorStandEditorPlugin plugin) { + this.plugin = plugin; + players = new HashMap<>(); + coarseAdj = Util.FULL_CIRCLE / plugin.getCoarseConfig(); + fineAdj = Util.FULL_CIRCLE / plugin.getFineConfig(); + coarseMov = 1; + fineMov = .03125; // 1/32 + counter = new TickCounter(); + Bukkit.getServer().getScheduler().runTaskTimer(plugin, counter, 0, 1); + } + + class TickCounter implements Runnable { + long ticks = 0; //I am optimistic + + @Override + public void run() { + ticks++; + } + + public long getTime() { + return ticks; + } + } +} diff --git a/src/main/java/io/github/rypofalem/armorstandeditor/metricshandler/MetricsHandler.java b/src/main/java/io/github/rypofalem/armorstandeditor/metricshandler/MetricsHandler.java index ed64ad0f..e828e3ec 100644 --- a/src/main/java/io/github/rypofalem/armorstandeditor/metricshandler/MetricsHandler.java +++ b/src/main/java/io/github/rypofalem/armorstandeditor/metricshandler/MetricsHandler.java @@ -9,7 +9,8 @@ public class MetricsHandler { private static final int PLUGIN_ID = 12668; public ArmorStandEditorPlugin plugin; - public MetricsHandler(){ + public MetricsHandler(ArmorStandEditorPlugin plugin){ + this.plugin = plugin; Metrics metrics = new Metrics(plugin, PLUGIN_ID); metrics.addCustomChart(new Metrics.SimplePie("dev_flag_enabled", () -> valueOf(plugin.isDebug()))); metrics.addCustomChart(new Metrics.SimplePie("require_sneaking", () -> valueOf(plugin.getRequireSneakingConfig()))); From 5ea84bfc87e967ec575a39d398adef3525af08f9 Mon Sep 17 00:00:00 2001 From: Wolfieheart Date: Sat, 4 Jan 2025 19:20:43 +0100 Subject: [PATCH 38/40] [CORE] Ground work for Menus with API Events, PlayerEditor basics, Language Files and so on. Signed-off-by: Wolfieheart --- .../ArmorStandEditorPlugin.java | 10 +++- .../armorstandeditor/PlayerEditor.java | 8 +++ .../api/EquipmentMenuOpenedEvent.java | 50 ++++++++++++++++ .../api/interfaces/OpenMenuEvent.java | 21 +++++++ .../armorstandeditor/menu/ASEHolder.java | 7 +-- .../armorstandeditor/menu/EditorMenu.java | 9 +++ .../armorstandeditor/menu/EquipmentMenu.java | 60 +++++++++++++++++++ 7 files changed, 158 insertions(+), 7 deletions(-) create mode 100644 src/main/java/io/github/rypofalem/armorstandeditor/api/EquipmentMenuOpenedEvent.java create mode 100644 src/main/java/io/github/rypofalem/armorstandeditor/api/interfaces/OpenMenuEvent.java create mode 100644 src/main/java/io/github/rypofalem/armorstandeditor/menu/EditorMenu.java create mode 100644 src/main/java/io/github/rypofalem/armorstandeditor/menu/EquipmentMenu.java diff --git a/src/main/java/io/github/rypofalem/armorstandeditor/ArmorStandEditorPlugin.java b/src/main/java/io/github/rypofalem/armorstandeditor/ArmorStandEditorPlugin.java index e7a860b4..73efcd90 100644 --- a/src/main/java/io/github/rypofalem/armorstandeditor/ArmorStandEditorPlugin.java +++ b/src/main/java/io/github/rypofalem/armorstandeditor/ArmorStandEditorPlugin.java @@ -2,6 +2,7 @@ import io.github.rypofalem.armorstandeditor.devtools.Debug; +import io.github.rypofalem.armorstandeditor.language.Lang; import io.github.rypofalem.armorstandeditor.metricshandler.MetricsHandler; import net.kyori.adventure.text.format.NamedTextColor; import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; @@ -26,6 +27,7 @@ public final class ArmorStandEditorPlugin extends JavaPlugin { private Debug debug = new Debug(this); MetricsHandler metricsHandler; protected PlayerEditorManager editorManager; + private Lang language; // Server Software Check True/False boolean isFolia; @@ -116,6 +118,7 @@ public void onEnable() { doScoreboardSetup(); //TODO: Readd Languages here! + language = new Lang(getLanguageConfig(), this); // Get all the Configuration Options coarseRotation = getCoarseConfig(); @@ -288,10 +291,13 @@ private void doPerWorldSupportSetup(boolean perWorldSupport){ public String getToolTypeConfig() { return getConfig().getString("tool");} public String getToolNameConfig() { return getConfig().getString("editToolName");} public String getToolLoreConfig(){ return getConfig().getString("toolLore", null); } + public String getLanguageConfig(){ return getConfig().getString("lang"); } public Integer getEditToolDataConfig() { return getConfig().getInt("toolData", Integer.MIN_VALUE); } - public List getAllowedWorldListConfig(){ - return getConfig().getList("allowed-worlds", null); + public List getAllowedWorldListConfig(){ return getConfig().getList("allowed-worlds", null); } + + public Lang getLanguage(){ + return language; } diff --git a/src/main/java/io/github/rypofalem/armorstandeditor/PlayerEditor.java b/src/main/java/io/github/rypofalem/armorstandeditor/PlayerEditor.java index 9dd54ae8..c22f9032 100644 --- a/src/main/java/io/github/rypofalem/armorstandeditor/PlayerEditor.java +++ b/src/main/java/io/github/rypofalem/armorstandeditor/PlayerEditor.java @@ -47,4 +47,12 @@ public PlayerEditorManager getManager() { return plugin.editorManager; } + public Player getPlayer() { + return plugin.getServer().getPlayer(getUUID()); + } + + public UUID getUUID() { + return uuid; + } + } diff --git a/src/main/java/io/github/rypofalem/armorstandeditor/api/EquipmentMenuOpenedEvent.java b/src/main/java/io/github/rypofalem/armorstandeditor/api/EquipmentMenuOpenedEvent.java new file mode 100644 index 00000000..b79c13cc --- /dev/null +++ b/src/main/java/io/github/rypofalem/armorstandeditor/api/EquipmentMenuOpenedEvent.java @@ -0,0 +1,50 @@ +package io.github.rypofalem.armorstandeditor.api; + +import io.github.rypofalem.armorstandeditor.api.interfaces.OpenMenuEvent; +import io.github.rypofalem.armorstandeditor.menu.EditorMenu; +import lombok.Getter; +import lombok.Setter; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; +import org.jetbrains.annotations.NotNull; + +public class EquipmentMenuOpenedEvent extends OpenMenuEvent implements Cancellable { + + @Getter + @Setter + private boolean isCancelled = false; + + @Getter + protected final Player player; + + @Getter + protected final EditorMenu edtMenu; + + private static final HandlerList HANDLERS = new HandlerList(); + + public EquipmentMenuOpenedEvent(Player player, EditorMenu edtMenu){ + super(player, edtMenu); + this.player = player; + this.edtMenu = edtMenu; + } + + @Override + public @NotNull HandlerList getHandlers() { + return HANDLERS; + } + + public static HandlerList getHandlerList() { + return HANDLERS; + } + @Override + public boolean isCancelled() { + return this.isCancelled; + } + + @Override + public void setCancelled(boolean isCancelled) { + this.isCancelled = isCancelled; + } + +} diff --git a/src/main/java/io/github/rypofalem/armorstandeditor/api/interfaces/OpenMenuEvent.java b/src/main/java/io/github/rypofalem/armorstandeditor/api/interfaces/OpenMenuEvent.java new file mode 100644 index 00000000..2d287e7d --- /dev/null +++ b/src/main/java/io/github/rypofalem/armorstandeditor/api/interfaces/OpenMenuEvent.java @@ -0,0 +1,21 @@ +package io.github.rypofalem.armorstandeditor.api.interfaces; + +import io.github.rypofalem.armorstandeditor.menu.EditorMenu; +import lombok.Getter; +import org.bukkit.entity.Player; +import org.bukkit.event.Event; + +public abstract class OpenMenuEvent extends Event { + + @Getter + protected final Player player; + + @Getter + protected final EditorMenu edtMenu; + + public OpenMenuEvent(Player player, EditorMenu edtMenu){ + this.player = player; + this.edtMenu = edtMenu; + } + +} diff --git a/src/main/java/io/github/rypofalem/armorstandeditor/menu/ASEHolder.java b/src/main/java/io/github/rypofalem/armorstandeditor/menu/ASEHolder.java index f10c64ff..61761d52 100644 --- a/src/main/java/io/github/rypofalem/armorstandeditor/menu/ASEHolder.java +++ b/src/main/java/io/github/rypofalem/armorstandeditor/menu/ASEHolder.java @@ -2,10 +2,7 @@ import org.bukkit.inventory.InventoryHolder; import org.bukkit.inventory.Inventory; +import org.jetbrains.annotations.NotNull; -public class ASEHolder implements InventoryHolder { - @Override - public Inventory getInventory() { - return null; - } +public interface ASEHolder extends InventoryHolder { } diff --git a/src/main/java/io/github/rypofalem/armorstandeditor/menu/EditorMenu.java b/src/main/java/io/github/rypofalem/armorstandeditor/menu/EditorMenu.java new file mode 100644 index 00000000..ce05e0fd --- /dev/null +++ b/src/main/java/io/github/rypofalem/armorstandeditor/menu/EditorMenu.java @@ -0,0 +1,9 @@ +package io.github.rypofalem.armorstandeditor.menu; + +import org.bukkit.entity.ArmorStand; + +public interface EditorMenu extends ASEHolder{ + void open(); + void fillInventory(); + ArmorStand getArmorStand(); +} diff --git a/src/main/java/io/github/rypofalem/armorstandeditor/menu/EquipmentMenu.java b/src/main/java/io/github/rypofalem/armorstandeditor/menu/EquipmentMenu.java new file mode 100644 index 00000000..e3bd72f5 --- /dev/null +++ b/src/main/java/io/github/rypofalem/armorstandeditor/menu/EquipmentMenu.java @@ -0,0 +1,60 @@ +package io.github.rypofalem.armorstandeditor.menu; + +import io.github.rypofalem.armorstandeditor.PlayerEditor; +import io.github.rypofalem.armorstandeditor.api.EquipmentMenuOpenedEvent; +import net.kyori.adventure.text.Component; +import org.bukkit.Bukkit; +import org.bukkit.entity.ArmorStand; +import org.bukkit.inventory.EntityEquipment; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.NotNull; + +public class EquipmentMenu implements EditorMenu{ + + private int HELMET_INDEX; + private int CHEST_INDEX; + private int PANTS_INDEX; + private int BOOTS_INDEX; + private int RHAND_INDEX; + private int LHAND_INDEX; + + Inventory equipMenu; + private PlayerEditor pe; + private ArmorStand armorStand; + static String menuName = "ArmorStand Equipment"; + + public EquipmentMenu(PlayerEditor pe, ArmorStand as){ + this.pe = pe; + this.armorStand = as; + menuName = pe.plugin.getLanguage().getMessage("equiptitle", "menutitle"); + equipMenu = Bukkit.createInventory(this, 18, Component.text(menuName)); + } + + @Override + public void open() { + EquipmentMenuOpenedEvent event = new EquipmentMenuOpenedEvent(pe.getPlayer(), this); + Bukkit.getPluginManager().callEvent(event); + if(event.isCancelled()) return; + fillInventory(); + pe.getPlayer().openInventory(this.equipMenu); + + } + + @Override + public void fillInventory() { + equipMenu.clear(); + EntityEquipment equipmentOnAS = armorStand.getEquipment(); + //ItemStack + } + + @Override + public ArmorStand getArmorStand() { + return this.armorStand; + } + + @Override + public @NotNull Inventory getInventory() { + return equipMenu; + } +} From b47b5cd6d39b875407ae4debeb86ffecc4f3e4fa Mon Sep 17 00:00:00 2001 From: Wolfieheart Date: Wed, 22 Jan 2025 19:58:11 +0100 Subject: [PATCH 39/40] [MENU] First Menu Recoded and a few extras added that i didnt foresee needing but apparently do... WHOOOPS! Signed-off-by: Wolfieheart --- .../ArmorStandEditorPlugin.java | 15 ++-- .../armorstandeditor/menu/EquipmentMenu.java | 73 +++++++++++++++---- 2 files changed, 70 insertions(+), 18 deletions(-) diff --git a/src/main/java/io/github/rypofalem/armorstandeditor/ArmorStandEditorPlugin.java b/src/main/java/io/github/rypofalem/armorstandeditor/ArmorStandEditorPlugin.java index 73efcd90..943aa8e9 100644 --- a/src/main/java/io/github/rypofalem/armorstandeditor/ArmorStandEditorPlugin.java +++ b/src/main/java/io/github/rypofalem/armorstandeditor/ArmorStandEditorPlugin.java @@ -8,6 +8,7 @@ import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; import org.bukkit.Material; +import org.bukkit.NamespacedKey; import org.bukkit.World; import org.bukkit.scoreboard.Scoreboard; import org.bukkit.scoreboard.Team; @@ -24,6 +25,7 @@ public final class ArmorStandEditorPlugin extends JavaPlugin { // Classes private static ArmorStandEditorPlugin instance; + private NamespacedKey iconKey; private Debug debug = new Debug(this); MetricsHandler metricsHandler; protected PlayerEditorManager editorManager; @@ -89,7 +91,7 @@ public void onEnable() { debug.log("Enabling ASE, Getting ASE Version and logging Server Checks"); - aseVersion = getConfig().getString("version"); + aseVersion = getASEVersion(); aseVersionToLog = String.format("Plugin Version: v%s", aseVersion); getLogger().log(Level.INFO,"======= ArmorStandEditor ======="); getLogger().log(Level.INFO, aseVersionToLog ); @@ -274,6 +276,9 @@ private void doPerWorldSupportSetup(boolean perWorldSupport){ // Config Methods as Getters - Useful for Config Reload etc. public boolean isDebug() { return getConfig().getBoolean("debugFlag"); } + public String getASEVersion() { + return getConfig().getString("version"); + } public boolean getRequireToolNameConfig() { return getConfig().getBoolean("requireToolName", false); } public boolean getRequireToolDataConfig() { return getConfig().getBoolean("requireToolData", false); } public boolean getRequireToolLoreConfig() { return getConfig().getBoolean("requireToolLore", false); } @@ -282,24 +287,24 @@ private void doPerWorldSupportSetup(boolean perWorldSupport){ public boolean getInvisibleArmorStandsConfig() { return getConfig().getBoolean("armorStandVisibility", false); } public boolean getInvisibleItemFramesConfig() { return getConfig().getBoolean("invisibleItemFrames", false); } public boolean getSendToActionBarConfig() { return getConfig().getBoolean("sendMessagesToActionBar", false); } - public double getCoarseConfig() { return getConfig().getDouble("coarse"); } public double getFineConfig() { return getConfig().getDouble("fine"); } public double getMinScaleConfig() { return getConfig().getDouble("minScaleValue"); } public double getMaxScaleConfig() { return getConfig().getDouble("maxScaleValue"); } - public String getToolTypeConfig() { return getConfig().getString("tool");} public String getToolNameConfig() { return getConfig().getString("editToolName");} public String getToolLoreConfig(){ return getConfig().getString("toolLore", null); } public String getLanguageConfig(){ return getConfig().getString("lang"); } - public Integer getEditToolDataConfig() { return getConfig().getInt("toolData", Integer.MIN_VALUE); } public List getAllowedWorldListConfig(){ return getConfig().getList("allowed-worlds", null); } - public Lang getLanguage(){ return language; } + public NamespacedKey getIconKey() { + if (iconKey == null) iconKey = new NamespacedKey(this, "command_icon"); + return iconKey; + } } diff --git a/src/main/java/io/github/rypofalem/armorstandeditor/menu/EquipmentMenu.java b/src/main/java/io/github/rypofalem/armorstandeditor/menu/EquipmentMenu.java index e3bd72f5..98535d8c 100644 --- a/src/main/java/io/github/rypofalem/armorstandeditor/menu/EquipmentMenu.java +++ b/src/main/java/io/github/rypofalem/armorstandeditor/menu/EquipmentMenu.java @@ -2,52 +2,99 @@ import io.github.rypofalem.armorstandeditor.PlayerEditor; import io.github.rypofalem.armorstandeditor.api.EquipmentMenuOpenedEvent; +import io.github.rypofalem.armorstandeditor.devtools.Debug; import net.kyori.adventure.text.Component; + import org.bukkit.Bukkit; +import org.bukkit.Material; import org.bukkit.entity.ArmorStand; import org.bukkit.inventory.EntityEquipment; import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemFlag; import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.persistence.PersistentDataType; import org.jetbrains.annotations.NotNull; -public class EquipmentMenu implements EditorMenu{ +import java.util.ArrayList; + +import static net.kyori.adventure.text.Component.text; - private int HELMET_INDEX; - private int CHEST_INDEX; - private int PANTS_INDEX; - private int BOOTS_INDEX; - private int RHAND_INDEX; - private int LHAND_INDEX; +public class EquipmentMenu implements EditorMenu { Inventory equipMenu; private PlayerEditor pe; private ArmorStand armorStand; - static String menuName = "ArmorStand Equipment"; + String menuName; + public Debug debug; public EquipmentMenu(PlayerEditor pe, ArmorStand as){ this.pe = pe; this.armorStand = as; menuName = pe.plugin.getLanguage().getMessage("equiptitle", "menutitle"); - equipMenu = Bukkit.createInventory(this, 18, Component.text(menuName)); + this.debug = new Debug(pe.plugin); + equipMenu = Bukkit.createInventory(this, 18, text(menuName)); } @Override public void open() { + EquipmentMenuOpenedEvent event = new EquipmentMenuOpenedEvent(pe.getPlayer(), this); Bukkit.getPluginManager().callEvent(event); if(event.isCancelled()) return; - fillInventory(); - pe.getPlayer().openInventory(this.equipMenu); + if(pe.getPlayer().hasPermission("asedit.equipment")) { + fillInventory(); + debug.log("Player '" + pe.getPlayer().getName() + "' has opened the Equipment Menu."); + pe.getPlayer().openInventory(this.equipMenu); + } } @Override public void fillInventory() { equipMenu.clear(); - EntityEquipment equipmentOnAS = armorStand.getEquipment(); - //ItemStack + EntityEquipment equipment = armorStand.getEquipment(); + ItemStack helmet = equipment.getHelmet(); + ItemStack chest = equipment.getChestplate(); + ItemStack pants = equipment.getLeggings(); + ItemStack feetsies = equipment.getBoots(); + ItemStack rightHand = equipment.getItemInMainHand(); + ItemStack leftHand = equipment.getItemInOffHand(); + equipment.clear(); + + ItemStack disabledIcon = new ItemStack(Material.BARRIER); + ItemMeta meta = disabledIcon.getItemMeta(); + meta.displayName(text(pe.plugin.getLanguage().getMessage("disabled", "warn"))); //equipslot.msg