From a5dd9b74a96da6ad532bd0af0815920875f3b451 Mon Sep 17 00:00:00 2001 From: jascotty2 Date: Fri, 4 Oct 2019 09:08:58 -0500 Subject: [PATCH 01/21] change getConfig to be easier to use in external API --- Core/src/main/java/com/songoda/core/SongodaPlugin.java | 8 ++++++-- .../core/configuration/editor/PluginConfigGui.java | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/Core/src/main/java/com/songoda/core/SongodaPlugin.java b/Core/src/main/java/com/songoda/core/SongodaPlugin.java index b65d3d2f..9c2595fc 100644 --- a/Core/src/main/java/com/songoda/core/SongodaPlugin.java +++ b/Core/src/main/java/com/songoda/core/SongodaPlugin.java @@ -9,6 +9,7 @@ import java.util.logging.Level; import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.command.ConsoleCommandSender; +import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.plugin.java.JavaPlugin; /** @@ -44,11 +45,14 @@ public abstract class SongodaPlugin extends JavaPlugin { public abstract List getExtraConfig(); @Override - public ConfigFileConfigurationAdapter getConfig() { - // todo? change prototype to FileConfiguration? This seems to cause development issues due to shading. + public FileConfiguration getConfig() { return config.getFileConfig(); } + public Config getCoreConfig() { + return config; + } + @Override public void reloadConfig​() { config.load(); diff --git a/Core/src/main/java/com/songoda/core/configuration/editor/PluginConfigGui.java b/Core/src/main/java/com/songoda/core/configuration/editor/PluginConfigGui.java index b980cb38..944fb13d 100644 --- a/Core/src/main/java/com/songoda/core/configuration/editor/PluginConfigGui.java +++ b/Core/src/main/java/com/songoda/core/configuration/editor/PluginConfigGui.java @@ -36,7 +36,7 @@ public class PluginConfigGui extends SimplePagedGui { this.plugin = plugin; // collect list of plugins - configs.put(plugin.getConfig().getCoreConfig().getFile().getName(), plugin.getConfig().getCoreConfig()); + configs.put(plugin.getCoreConfig().getFile().getName(), plugin.getCoreConfig()); List more = plugin.getExtraConfig(); if (more != null && !more.isEmpty()) { for (Config cfg : more) { From 8e2befa2a41f7450c3024674fca3592c10bb0a78 Mon Sep 17 00:00:00 2001 From: jascotty2 Date: Fri, 4 Oct 2019 11:35:24 -0500 Subject: [PATCH 02/21] update doubleGui functions --- .../java/com/songoda/core/SongodaPlugin.java | 1 - .../java/com/songoda/core/gui/DoubleGui.java | 37 +++++++++++++++++++ .../main/java/com/songoda/core/gui/Gui.java | 17 +++++++++ .../java/com/songoda/core/locale/Message.java | 2 +- 4 files changed, 55 insertions(+), 2 deletions(-) diff --git a/Core/src/main/java/com/songoda/core/SongodaPlugin.java b/Core/src/main/java/com/songoda/core/SongodaPlugin.java index 9c2595fc..15e38515 100644 --- a/Core/src/main/java/com/songoda/core/SongodaPlugin.java +++ b/Core/src/main/java/com/songoda/core/SongodaPlugin.java @@ -1,7 +1,6 @@ package com.songoda.core; import com.songoda.core.configuration.Config; -import com.songoda.core.configuration.ConfigFileConfigurationAdapter; import com.songoda.core.locale.Locale; import com.songoda.core.utils.Metrics; import java.util.List; diff --git a/Core/src/main/java/com/songoda/core/gui/DoubleGui.java b/Core/src/main/java/com/songoda/core/gui/DoubleGui.java index 1dfadfc2..856f2c89 100644 --- a/Core/src/main/java/com/songoda/core/gui/DoubleGui.java +++ b/Core/src/main/java/com/songoda/core/gui/DoubleGui.java @@ -47,6 +47,11 @@ public class DoubleGui extends Gui { allowDropItems = false; } + public DoubleGui(Gui parent) { + super(parent); + allowDropItems = false; + } + public int getPlayerRows() { return playerRows; } @@ -85,6 +90,38 @@ public class DoubleGui extends Gui { return this; } + public DoubleGui setPlayerUnlockedRange(int cellFirst, int cellLast) { + final int last = invOffset(cellLast); + for (int cell = invOffset(cellFirst); cell <= last; ++cell) { + unlockedCells.put(cell, true); + } + return this; + } + + public DoubleGui setPlayerUnlockedRange(int cellFirst, int cellLast, boolean open) { + final int last = invOffset(cellLast); + for (int cell = invOffset(cellFirst); cell <= last; ++cell) { + unlockedCells.put(cell, open); + } + return this; + } + + public DoubleGui setPlayerUnlockedRange(int cellRowFirst, int cellColFirst, int cellRowLast, int cellColLast) { + final int last = invOffset(cellColLast + cellRowLast * 9); + for (int cell = invOffset(cellColFirst + cellRowFirst * 9); cell <= last; ++cell) { + unlockedCells.put(cell, true); + } + return this; + } + + public DoubleGui setPlayerUnlockedRange(int cellRowFirst, int cellColFirst, int cellRowLast, int cellColLast, boolean open) { + final int last = invOffset(cellColLast + cellRowLast * 9); + for (int cell = invOffset(cellColFirst + cellRowFirst * 9); cell <= last; ++cell) { + unlockedCells.put(cell, open); + } + return this; + } + public DoubleGui setPlayerItem(int cell, ItemStack item) { cellItems.put(invOffset(cell), item); if (open && cell >= 0 && cell < 36) { diff --git a/Core/src/main/java/com/songoda/core/gui/Gui.java b/Core/src/main/java/com/songoda/core/gui/Gui.java index 82da0cae..2797b1f5 100644 --- a/Core/src/main/java/com/songoda/core/gui/Gui.java +++ b/Core/src/main/java/com/songoda/core/gui/Gui.java @@ -181,6 +181,14 @@ public class Gui { return this; } + @NotNull + public Gui setUnlockedRange(int cellFirst, int cellLast, boolean open) { + for (int cell = cellFirst; cell <= cellLast; ++cell) { + unlockedCells.put(cell, open); + } + return this; + } + @NotNull public Gui setUnlockedRange(int cellRowFirst, int cellColFirst, int cellRowLast, int cellColLast) { final int last = cellColLast + cellRowLast * 9; @@ -190,6 +198,15 @@ public class Gui { return this; } + @NotNull + public Gui setUnlockedRange(int cellRowFirst, int cellColFirst, int cellRowLast, int cellColLast, boolean open) { + final int last = cellColLast + cellRowLast * 9; + for (int cell = cellColFirst + cellRowFirst * 9; cell <= last; ++cell) { + unlockedCells.put(cell, open); + } + return this; + } + @NotNull public Gui setUnlocked(int cell, boolean open) { unlockedCells.put(cell, open); diff --git a/Core/src/main/java/com/songoda/core/locale/Message.java b/Core/src/main/java/com/songoda/core/locale/Message.java index e30c586f..a19256cb 100644 --- a/Core/src/main/java/com/songoda/core/locale/Message.java +++ b/Core/src/main/java/com/songoda/core/locale/Message.java @@ -119,7 +119,7 @@ public class Message { */ public Message processPlaceholder(String placeholder, Object replacement) { final String place = Matcher.quoteReplacement(placeholder); - this.message = message.replaceAll("%" + place + "%|\\{" + place +"\\}", Matcher.quoteReplacement(replacement.toString())); + this.message = message.replaceAll("%" + place + "%|\\{" + place +"\\}", replacement == null ? "" : Matcher.quoteReplacement(replacement.toString())); return this; } From 28386e03afb99b6605c67187f6603fa8daae3d4c Mon Sep 17 00:00:00 2001 From: jascotty2 Date: Fri, 4 Oct 2019 11:46:05 -0500 Subject: [PATCH 03/21] fix block util cast error --- Core/src/main/java/com/songoda/core/utils/BlockUtils.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/src/main/java/com/songoda/core/utils/BlockUtils.java b/Core/src/main/java/com/songoda/core/utils/BlockUtils.java index 2ef62d74..49b86a48 100644 --- a/Core/src/main/java/com/songoda/core/utils/BlockUtils.java +++ b/Core/src/main/java/com/songoda/core/utils/BlockUtils.java @@ -442,7 +442,7 @@ public class BlockUtils { CompatibleMaterial mat = CompatibleMaterial.getMaterial(block.getType()); if (mat != null && mat.isCrop() && block.getData() < (mat == CompatibleMaterial.BEETROOTS ? 3 : 7)) { try { - legacySetBlockData.invoke(block, (byte) block.getData() + 1); + legacySetBlockData.invoke(block, (byte) (block.getData() + 1)); } catch (Exception ex) { Logger.getLogger(BlockUtils.class.getName()).log(Level.SEVERE, "Unexpected method error", ex); } From b4cb706b186f9ff73028b7c0069ffec3e1132080 Mon Sep 17 00:00:00 2001 From: jascotty2 Date: Fri, 4 Oct 2019 14:58:05 -0500 Subject: [PATCH 04/21] change config accessor materials to be non-null --- .../songoda/core/configuration/ConfigSetting.java | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/Core/src/main/java/com/songoda/core/configuration/ConfigSetting.java b/Core/src/main/java/com/songoda/core/configuration/ConfigSetting.java index 15d0b862..d0850ba4 100644 --- a/Core/src/main/java/com/songoda/core/configuration/ConfigSetting.java +++ b/Core/src/main/java/com/songoda/core/configuration/ConfigSetting.java @@ -106,12 +106,17 @@ public class ConfigSetting { @NotNull public CompatibleMaterial getMaterial() { - CompatibleMaterial m = getMaterial(null); - return m != null ? m : CompatibleMaterial.STONE; + CompatibleMaterial val = CompatibleMaterial.getMaterial(config.getString(key)); + + if (val == null) { + System.out.println(String.format("Config value \"%s\" has an invalid material name: \"%s\"", key, val)); + } + + return val != null ? val : CompatibleMaterial.STONE; } - @Nullable - public CompatibleMaterial getMaterial(@Nullable CompatibleMaterial def) { + @NotNull + public CompatibleMaterial getMaterial(@NotNull CompatibleMaterial def) { //return config.getMaterial(key, def); String val = config.getString(key); CompatibleMaterial mat = val != null ? CompatibleMaterial.getMaterial(val) : null; From 4fa8ed2e582b399d12b3b49cc617de8a6c7375f8 Mon Sep 17 00:00:00 2001 From: jascotty2 Date: Fri, 4 Oct 2019 15:41:19 -0500 Subject: [PATCH 05/21] change config accessor materials to be non-null --- .../java/com/songoda/core/configuration/ConfigSetting.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Core/src/main/java/com/songoda/core/configuration/ConfigSetting.java b/Core/src/main/java/com/songoda/core/configuration/ConfigSetting.java index d0850ba4..233fafdd 100644 --- a/Core/src/main/java/com/songoda/core/configuration/ConfigSetting.java +++ b/Core/src/main/java/com/songoda/core/configuration/ConfigSetting.java @@ -106,13 +106,14 @@ public class ConfigSetting { @NotNull public CompatibleMaterial getMaterial() { - CompatibleMaterial val = CompatibleMaterial.getMaterial(config.getString(key)); + String val = config.getString(key); + CompatibleMaterial mat = CompatibleMaterial.getMaterial(config.getString(key)); - if (val == null) { + if (mat == null) { System.out.println(String.format("Config value \"%s\" has an invalid material name: \"%s\"", key, val)); } - return val != null ? val : CompatibleMaterial.STONE; + return mat != null ? mat : CompatibleMaterial.STONE; } @NotNull From 3ae4f705bc7062f06726f7565727e533a95567e3 Mon Sep 17 00:00:00 2001 From: jascotty2 Date: Fri, 4 Oct 2019 15:42:39 -0500 Subject: [PATCH 06/21] Version 2.2.0 --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index e6fb4860..ed8f223e 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -4,7 +4,7 @@ stages: variables: name: "SongodaCore" path: "/builds/$CI_PROJECT_PATH" - version: "2.1.10" + version: "2.2.0" build: stage: build From d1b380429651cf1f6780c511dbf53b9fc5b789b9 Mon Sep 17 00:00:00 2001 From: jascotty2 Date: Sun, 6 Oct 2019 09:50:14 -0500 Subject: [PATCH 07/21] trim trailing color char from gui title if trimming --- Core/src/main/java/com/songoda/core/gui/Gui.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Core/src/main/java/com/songoda/core/gui/Gui.java b/Core/src/main/java/com/songoda/core/gui/Gui.java index 2797b1f5..ae1aa849 100644 --- a/Core/src/main/java/com/songoda/core/gui/Gui.java +++ b/Core/src/main/java/com/songoda/core/gui/Gui.java @@ -789,8 +789,8 @@ public class Gui { protected static String trimTitle(String title) { if(title == null) { return ""; - } else if (title != null && title.length() > 32) { - return title.substring(0, 31); + } else if (title.length() > 32) { + return title.charAt(30) == '\u00A7' ? title.substring(0, 30) : title.substring(0, 31); } return title; } From 78a7c236dbb423677b29e7b1b7650e1ba3635afd Mon Sep 17 00:00:00 2001 From: jascotty2 Date: Sun, 6 Oct 2019 10:46:45 -0500 Subject: [PATCH 08/21] less detail for locale download errors --- .../main/java/com/songoda/core/core/LocaleModule.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Core/src/main/java/com/songoda/core/core/LocaleModule.java b/Core/src/main/java/com/songoda/core/core/LocaleModule.java index 8d8a5908..3a4c617d 100644 --- a/Core/src/main/java/com/songoda/core/core/LocaleModule.java +++ b/Core/src/main/java/com/songoda/core/core/LocaleModule.java @@ -1,13 +1,14 @@ package com.songoda.core.core; import com.songoda.core.locale.Locale; -import org.json.simple.JSONArray; -import org.json.simple.JSONObject; - +import com.sun.istack.internal.logging.Logger; import java.io.IOException; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; +import java.util.logging.Level; +import org.json.simple.JSONArray; +import org.json.simple.JSONObject; public class LocaleModule implements PluginInfoModule { @@ -25,7 +26,7 @@ public class LocaleModule implements PluginInfoModule { } } } catch (IOException e) { - e.printStackTrace(); + Logger.getLogger(LocaleModule.class).log(Level.INFO, "Failed to check for locale files: " + e.getMessage()); } } From 9c4b5ae948422db1615c36d3b6fa621ae365d4dc Mon Sep 17 00:00:00 2001 From: jascotty2 Date: Sun, 6 Oct 2019 11:09:45 -0500 Subject: [PATCH 09/21] fix anvil dupe glitch, add methods for automatically setting result text --- .../com/songoda/core/core/LocaleModule.java | 4 +-- .../java/com/songoda/core/gui/AnvilGui.java | 29 ++++++++++++++++++- .../java/com/songoda/core/gui/GuiManager.java | 6 ++++ .../src/com/songoda/core/nms/CustomAnvil.java | 8 +++++ .../core/nms/methods/AnvilTextChange.java | 6 ++++ .../songoda/core/nms/v1_10_R1/AnvilView.java | 13 ++++++++- .../songoda/core/nms/v1_11_R1/AnvilView.java | 12 ++++++++ .../songoda/core/nms/v1_12_R1/AnvilView.java | 12 ++++++++ .../songoda/core/nms/v1_13_R1/AnvilView.java | 12 ++++++++ .../songoda/core/nms/v1_13_R2/AnvilView.java | 12 ++++++++ .../songoda/core/nms/v1_14_R1/AnvilView.java | 13 +++++++++ .../songoda/core/nms/v1_8_R1/AnvilView.java | 12 ++++++++ .../songoda/core/nms/v1_8_R2/AnvilView.java | 12 ++++++++ .../songoda/core/nms/v1_8_R3/AnvilView.java | 12 ++++++++ .../songoda/core/nms/v1_9_R1/AnvilView.java | 12 ++++++++ .../songoda/core/nms/v1_9_R2/AnvilView.java | 12 ++++++++ 16 files changed, 183 insertions(+), 4 deletions(-) create mode 100644 NMS/NMS-API/src/com/songoda/core/nms/methods/AnvilTextChange.java diff --git a/Core/src/main/java/com/songoda/core/core/LocaleModule.java b/Core/src/main/java/com/songoda/core/core/LocaleModule.java index 3a4c617d..de425790 100644 --- a/Core/src/main/java/com/songoda/core/core/LocaleModule.java +++ b/Core/src/main/java/com/songoda/core/core/LocaleModule.java @@ -1,12 +1,12 @@ package com.songoda.core.core; import com.songoda.core.locale.Locale; -import com.sun.istack.internal.logging.Logger; import java.io.IOException; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; import java.util.logging.Level; +import java.util.logging.Logger; import org.json.simple.JSONArray; import org.json.simple.JSONObject; @@ -26,7 +26,7 @@ public class LocaleModule implements PluginInfoModule { } } } catch (IOException e) { - Logger.getLogger(LocaleModule.class).log(Level.INFO, "Failed to check for locale files: " + e.getMessage()); + Logger.getLogger(LocaleModule.class.getName()).log(Level.INFO, "Failed to check for locale files: " + e.getMessage()); } } diff --git a/Core/src/main/java/com/songoda/core/gui/AnvilGui.java b/Core/src/main/java/com/songoda/core/gui/AnvilGui.java index 0bc5c254..30b70d56 100644 --- a/Core/src/main/java/com/songoda/core/gui/AnvilGui.java +++ b/Core/src/main/java/com/songoda/core/gui/AnvilGui.java @@ -5,6 +5,8 @@ import com.songoda.core.gui.methods.Clickable; import com.songoda.core.nms.CoreNMS; import com.songoda.core.nms.CustomAnvil; import com.songoda.core.nms.NmsManager; +import java.util.Arrays; +import java.util.List; import org.bukkit.entity.Player; import org.bukkit.event.inventory.ClickType; import org.bukkit.inventory.Inventory; @@ -22,6 +24,7 @@ public class AnvilGui extends Gui { final Player player; CustomAnvil anvil; + List endPrompt = null; public AnvilGui(Player player) { this.player = player; @@ -58,6 +61,28 @@ public class AnvilGui extends Gui { return (AnvilGui) this.setItem(2, item); } + public AnvilGui setOutputPrompt(String str) { + endPrompt = Arrays.asList(str); + return this; + } + + public AnvilGui setOutputPrompt(String ... str) { + endPrompt = Arrays.asList(str); + return this; + } + + public AnvilGui setOutputPrompt(List str) { + endPrompt = str; + return this; + } + + void updateOutputPrompt() { + final ItemStack in; + if(endPrompt != null && (in = cellItems.get(0)) != null) { + setItem(2, GuiUtils.createButtonItem(in, endPrompt)); + } + } + public ItemStack getOutput() { return this.getItem(2); } @@ -78,7 +103,8 @@ public class AnvilGui extends Gui { } else if ((item = cellItems.get(1)) != null) { inventory.setItem(1, item); } else if (!acceptsItems) { - inventory.setItem(0, GuiUtils.createButtonItem(CompatibleMaterial.PAPER, " ", " ")); + cellItems.put(0, item = GuiUtils.createButtonItem(CompatibleMaterial.PAPER, " ", " ")); + inventory.setItem(0, item); } if ((item = cellItems.get(2)) != null) { inventory.setItem(2, item); @@ -95,6 +121,7 @@ public class AnvilGui extends Gui { anvil.setCustomTitle(title); anvil.setLevelCost(0); inventory = anvil.getInventory(); + anvil.setOnChange(this::updateOutputPrompt); } } } diff --git a/Core/src/main/java/com/songoda/core/gui/GuiManager.java b/Core/src/main/java/com/songoda/core/gui/GuiManager.java index 10c18e6d..8b6513ef 100644 --- a/Core/src/main/java/com/songoda/core/gui/GuiManager.java +++ b/Core/src/main/java/com/songoda/core/gui/GuiManager.java @@ -179,6 +179,9 @@ public class GuiManager { for(ItemStack it : gui.inventory.getContents()) { if(!gui.unlockedCells.getOrDefault(cell++, false) && clicked.isSimilar(it)) { event.setCancelled(true); + if(gui instanceof AnvilGui) { + ((AnvilGui) gui).anvil.update(); + } break; } } @@ -203,6 +206,9 @@ public class GuiManager { player.playSound(player.getLocation(), CompatibleSound.UI_BUTTON_CLICK.getSound(), 1F, 1F); } else if (!gui.acceptsItems || event.getAction() == InventoryAction.MOVE_TO_OTHER_INVENTORY) { event.setCancelled(true); + if(gui instanceof AnvilGui) { + ((AnvilGui) gui).anvil.update(); + } } } } diff --git a/NMS/NMS-API/src/com/songoda/core/nms/CustomAnvil.java b/NMS/NMS-API/src/com/songoda/core/nms/CustomAnvil.java index 7513ca34..93665ddc 100644 --- a/NMS/NMS-API/src/com/songoda/core/nms/CustomAnvil.java +++ b/NMS/NMS-API/src/com/songoda/core/nms/CustomAnvil.java @@ -1,5 +1,6 @@ package com.songoda.core.nms; +import com.songoda.core.nms.methods.AnvilTextChange; import org.bukkit.inventory.Inventory; import org.bukkit.inventory.ItemStack; @@ -25,6 +26,8 @@ public interface CustomAnvil { public void setRenameText(String text); + public void setOnChange(AnvilTextChange handler); + public ItemStack getLeftInput(); public ItemStack getRightInput(); @@ -43,4 +46,9 @@ public interface CustomAnvil { * Open this anvil for the provided player */ public void open(); + + /** + * Force a redraw of the output + */ + public void update(); } diff --git a/NMS/NMS-API/src/com/songoda/core/nms/methods/AnvilTextChange.java b/NMS/NMS-API/src/com/songoda/core/nms/methods/AnvilTextChange.java new file mode 100644 index 00000000..ab35618b --- /dev/null +++ b/NMS/NMS-API/src/com/songoda/core/nms/methods/AnvilTextChange.java @@ -0,0 +1,6 @@ +package com.songoda.core.nms.methods; + +public interface AnvilTextChange { + + void onChange(); +} diff --git a/NMS/NMS-v1_10_R1/src/com/songoda/core/nms/v1_10_R1/AnvilView.java b/NMS/NMS-v1_10_R1/src/com/songoda/core/nms/v1_10_R1/AnvilView.java index 3c0ae393..200860f6 100644 --- a/NMS/NMS-v1_10_R1/src/com/songoda/core/nms/v1_10_R1/AnvilView.java +++ b/NMS/NMS-v1_10_R1/src/com/songoda/core/nms/v1_10_R1/AnvilView.java @@ -1,6 +1,7 @@ package com.songoda.core.nms.v1_10_R1; import com.songoda.core.nms.CustomAnvil; +import com.songoda.core.nms.methods.AnvilTextChange; import java.lang.reflect.Field; import java.util.logging.Level; import java.util.logging.Logger; @@ -24,7 +25,7 @@ public class AnvilView extends ContainerAnvil implements CustomAnvil { private String title = "Repairing"; private int cost = -1; private boolean canUse = true; - + private AnvilTextChange textChange = null; // used for setting custom inventory static Field mc_ContainerAnvil_repairInventory; // subcontainer with only the result @@ -94,6 +95,11 @@ public class AnvilView extends ContainerAnvil implements CustomAnvil { } } + @Override + public void update() { + e(); + } + @Override public String getRenameText() { try { @@ -110,6 +116,11 @@ public class AnvilView extends ContainerAnvil implements CustomAnvil { this.a(text); } + @Override + public void setOnChange(AnvilTextChange handler) { + textChange = handler; + } + @Override public String getCustomTitle() { return title; diff --git a/NMS/NMS-v1_11_R1/src/com/songoda/core/nms/v1_11_R1/AnvilView.java b/NMS/NMS-v1_11_R1/src/com/songoda/core/nms/v1_11_R1/AnvilView.java index 0e12b1e6..8bb65e10 100644 --- a/NMS/NMS-v1_11_R1/src/com/songoda/core/nms/v1_11_R1/AnvilView.java +++ b/NMS/NMS-v1_11_R1/src/com/songoda/core/nms/v1_11_R1/AnvilView.java @@ -1,6 +1,7 @@ package com.songoda.core.nms.v1_11_R1; import com.songoda.core.nms.CustomAnvil; +import com.songoda.core.nms.methods.AnvilTextChange; import java.lang.reflect.Field; import java.util.logging.Level; import java.util.logging.Logger; @@ -24,6 +25,7 @@ public class AnvilView extends ContainerAnvil implements CustomAnvil { private String title = "Repairing"; private int cost = -1; private boolean canUse = true; + private AnvilTextChange textChange = null; // used for setting custom inventory static Field mc_ContainerAnvil_repairInventory; // subcontainer with only the result @@ -93,6 +95,11 @@ public class AnvilView extends ContainerAnvil implements CustomAnvil { } } + @Override + public void update() { + e(); + } + @Override public String getRenameText() { try { @@ -109,6 +116,11 @@ public class AnvilView extends ContainerAnvil implements CustomAnvil { this.a(text); } + @Override + public void setOnChange(AnvilTextChange handler) { + textChange = handler; + } + @Override public String getCustomTitle() { return title; diff --git a/NMS/NMS-v1_12_R1/src/com/songoda/core/nms/v1_12_R1/AnvilView.java b/NMS/NMS-v1_12_R1/src/com/songoda/core/nms/v1_12_R1/AnvilView.java index 205bfd87..5dd83627 100644 --- a/NMS/NMS-v1_12_R1/src/com/songoda/core/nms/v1_12_R1/AnvilView.java +++ b/NMS/NMS-v1_12_R1/src/com/songoda/core/nms/v1_12_R1/AnvilView.java @@ -1,6 +1,7 @@ package com.songoda.core.nms.v1_12_R1; import com.songoda.core.nms.CustomAnvil; +import com.songoda.core.nms.methods.AnvilTextChange; import java.lang.reflect.Field; import java.util.logging.Level; import java.util.logging.Logger; @@ -24,6 +25,7 @@ public class AnvilView extends ContainerAnvil implements CustomAnvil { private String title = "Repairing"; private int cost = -1; private boolean canUse = true; + private AnvilTextChange textChange = null; // used for setting custom inventory static Field mc_ContainerAnvil_repairInventory; // subcontainer with only the result @@ -81,6 +83,11 @@ public class AnvilView extends ContainerAnvil implements CustomAnvil { } } + @Override + public void update() { + e(); + } + @Override public String getRenameText() { return this.renameText; @@ -96,6 +103,11 @@ public class AnvilView extends ContainerAnvil implements CustomAnvil { return title; } + @Override + public void setOnChange(AnvilTextChange handler) { + textChange = handler; + } + @Override public void setCustomTitle(String title) { this.title = title; diff --git a/NMS/NMS-v1_13_R1/src/com/songoda/core/nms/v1_13_R1/AnvilView.java b/NMS/NMS-v1_13_R1/src/com/songoda/core/nms/v1_13_R1/AnvilView.java index 345a596f..fbf0dded 100644 --- a/NMS/NMS-v1_13_R1/src/com/songoda/core/nms/v1_13_R1/AnvilView.java +++ b/NMS/NMS-v1_13_R1/src/com/songoda/core/nms/v1_13_R1/AnvilView.java @@ -1,6 +1,7 @@ package com.songoda.core.nms.v1_13_R1; import com.songoda.core.nms.CustomAnvil; +import com.songoda.core.nms.methods.AnvilTextChange; import java.lang.reflect.Field; import java.util.logging.Level; import java.util.logging.Logger; @@ -24,6 +25,7 @@ public class AnvilView extends ContainerAnvil implements CustomAnvil { String title = "Repairing"; private int cost = -1; private boolean canUse = true; + private AnvilTextChange textChange = null; // used for setting custom inventory static Field mc_ContainerAnvil_repairInventory; // subcontainer with only the result @@ -82,6 +84,11 @@ public class AnvilView extends ContainerAnvil implements CustomAnvil { } } + @Override + public void update() { + d(); + } + @Override public String getRenameText() { return this.renameText; @@ -92,6 +99,11 @@ public class AnvilView extends ContainerAnvil implements CustomAnvil { this.a(text); } + @Override + public void setOnChange(AnvilTextChange handler) { + textChange = handler; + } + @Override public String getCustomTitle() { return title; diff --git a/NMS/NMS-v1_13_R2/src/com/songoda/core/nms/v1_13_R2/AnvilView.java b/NMS/NMS-v1_13_R2/src/com/songoda/core/nms/v1_13_R2/AnvilView.java index e2cc6306..00362fc3 100644 --- a/NMS/NMS-v1_13_R2/src/com/songoda/core/nms/v1_13_R2/AnvilView.java +++ b/NMS/NMS-v1_13_R2/src/com/songoda/core/nms/v1_13_R2/AnvilView.java @@ -1,6 +1,7 @@ package com.songoda.core.nms.v1_13_R2; import com.songoda.core.nms.CustomAnvil; +import com.songoda.core.nms.methods.AnvilTextChange; import java.lang.reflect.Field; import java.util.logging.Level; import java.util.logging.Logger; @@ -24,6 +25,7 @@ public class AnvilView extends ContainerAnvil implements CustomAnvil { private String title = "Repairing"; private int cost = -1; private boolean canUse = true; + private AnvilTextChange textChange = null; // used for setting custom inventory static Field mc_ContainerAnvil_repairInventory; // subcontainer with only the result @@ -82,6 +84,11 @@ public class AnvilView extends ContainerAnvil implements CustomAnvil { } } + @Override + public void update() { + d(); + } + @Override public String getRenameText() { return this.renameText; @@ -92,6 +99,11 @@ public class AnvilView extends ContainerAnvil implements CustomAnvil { this.a(text); } + @Override + public void setOnChange(AnvilTextChange handler) { + textChange = handler; + } + @Override public String getCustomTitle() { return title; diff --git a/NMS/NMS-v1_14_R1/src/com/songoda/core/nms/v1_14_R1/AnvilView.java b/NMS/NMS-v1_14_R1/src/com/songoda/core/nms/v1_14_R1/AnvilView.java index e687092b..99c98206 100644 --- a/NMS/NMS-v1_14_R1/src/com/songoda/core/nms/v1_14_R1/AnvilView.java +++ b/NMS/NMS-v1_14_R1/src/com/songoda/core/nms/v1_14_R1/AnvilView.java @@ -1,6 +1,7 @@ package com.songoda.core.nms.v1_14_R1; import com.songoda.core.nms.CustomAnvil; +import com.songoda.core.nms.methods.AnvilTextChange; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.logging.Level; @@ -29,6 +30,7 @@ public class AnvilView extends ContainerAnvil implements CustomAnvil { private String customTitle = "Repairing"; private int cost = -1; private boolean canUse = true; + private AnvilTextChange textChange = null; // used for setting custom inventory static Field mc_ContainerAnvil_repairInventory; // subcontainer with only the result @@ -131,6 +133,12 @@ public class AnvilView extends ContainerAnvil implements CustomAnvil { this.levelCost.set(cost); } } + textChange.onChange(); + } + + @Override + public void update() { + e(); } @Override @@ -143,6 +151,11 @@ public class AnvilView extends ContainerAnvil implements CustomAnvil { this.a(text); } + @Override + public void setOnChange(AnvilTextChange handler) { + textChange = handler; + } + @Override public String getCustomTitle() { return customTitle; diff --git a/NMS/NMS-v1_8_R1/src/com/songoda/core/nms/v1_8_R1/AnvilView.java b/NMS/NMS-v1_8_R1/src/com/songoda/core/nms/v1_8_R1/AnvilView.java index 67c2b119..50e9ea96 100644 --- a/NMS/NMS-v1_8_R1/src/com/songoda/core/nms/v1_8_R1/AnvilView.java +++ b/NMS/NMS-v1_8_R1/src/com/songoda/core/nms/v1_8_R1/AnvilView.java @@ -1,6 +1,7 @@ package com.songoda.core.nms.v1_8_R1; import com.songoda.core.nms.CustomAnvil; +import com.songoda.core.nms.methods.AnvilTextChange; import java.lang.reflect.Field; import java.util.logging.Level; import java.util.logging.Logger; @@ -23,6 +24,7 @@ public class AnvilView extends ContainerAnvil implements CustomAnvil { private String title = "Repairing"; private int cost = -1; private boolean canUse = true; + private AnvilTextChange textChange = null; // used for setting custom inventory static Field mc_ContainerAnvil_repairInventory; // subcontainer with only the result @@ -91,6 +93,11 @@ public class AnvilView extends ContainerAnvil implements CustomAnvil { } } + @Override + public void update() { + e(); + } + @Override public String getRenameText() { try { @@ -107,6 +114,11 @@ public class AnvilView extends ContainerAnvil implements CustomAnvil { this.a(text); } + @Override + public void setOnChange(AnvilTextChange handler) { + textChange = handler; + } + @Override public String getCustomTitle() { return title; diff --git a/NMS/NMS-v1_8_R2/src/com/songoda/core/nms/v1_8_R2/AnvilView.java b/NMS/NMS-v1_8_R2/src/com/songoda/core/nms/v1_8_R2/AnvilView.java index 9da27309..e7d20410 100644 --- a/NMS/NMS-v1_8_R2/src/com/songoda/core/nms/v1_8_R2/AnvilView.java +++ b/NMS/NMS-v1_8_R2/src/com/songoda/core/nms/v1_8_R2/AnvilView.java @@ -1,6 +1,7 @@ package com.songoda.core.nms.v1_8_R2; import com.songoda.core.nms.CustomAnvil; +import com.songoda.core.nms.methods.AnvilTextChange; import java.lang.reflect.Field; import java.util.logging.Level; import java.util.logging.Logger; @@ -23,6 +24,7 @@ public class AnvilView extends ContainerAnvil implements CustomAnvil { private String title = "Repairing"; private int cost = -1; private boolean canUse = true; + private AnvilTextChange textChange = null; // used for setting custom inventory static Field mc_ContainerAnvil_repairInventory; // subcontainer with only the result @@ -91,6 +93,11 @@ public class AnvilView extends ContainerAnvil implements CustomAnvil { } } + @Override + public void update() { + e(); + } + @Override public String getRenameText() { try { @@ -107,6 +114,11 @@ public class AnvilView extends ContainerAnvil implements CustomAnvil { this.a(text); } + @Override + public void setOnChange(AnvilTextChange handler) { + textChange = handler; + } + @Override public String getCustomTitle() { return title; diff --git a/NMS/NMS-v1_8_R3/src/com/songoda/core/nms/v1_8_R3/AnvilView.java b/NMS/NMS-v1_8_R3/src/com/songoda/core/nms/v1_8_R3/AnvilView.java index e2ff55c7..3381c44f 100644 --- a/NMS/NMS-v1_8_R3/src/com/songoda/core/nms/v1_8_R3/AnvilView.java +++ b/NMS/NMS-v1_8_R3/src/com/songoda/core/nms/v1_8_R3/AnvilView.java @@ -1,6 +1,7 @@ package com.songoda.core.nms.v1_8_R3; import com.songoda.core.nms.CustomAnvil; +import com.songoda.core.nms.methods.AnvilTextChange; import java.lang.reflect.Field; import java.util.logging.Level; import java.util.logging.Logger; @@ -23,6 +24,7 @@ public class AnvilView extends ContainerAnvil implements CustomAnvil { private String title = "Repairing"; private int cost = -1; private boolean canUse = true; + private AnvilTextChange textChange = null; // used for setting custom inventory static Field mc_ContainerAnvil_repairInventory; // subcontainer with only the result @@ -91,6 +93,11 @@ public class AnvilView extends ContainerAnvil implements CustomAnvil { } } + @Override + public void update() { + e(); + } + @Override public String getRenameText() { try { @@ -107,6 +114,11 @@ public class AnvilView extends ContainerAnvil implements CustomAnvil { this.a(text); } + @Override + public void setOnChange(AnvilTextChange handler) { + textChange = handler; + } + @Override public String getCustomTitle() { return title; diff --git a/NMS/NMS-v1_9_R1/src/com/songoda/core/nms/v1_9_R1/AnvilView.java b/NMS/NMS-v1_9_R1/src/com/songoda/core/nms/v1_9_R1/AnvilView.java index bf9ffc2f..1a338e94 100644 --- a/NMS/NMS-v1_9_R1/src/com/songoda/core/nms/v1_9_R1/AnvilView.java +++ b/NMS/NMS-v1_9_R1/src/com/songoda/core/nms/v1_9_R1/AnvilView.java @@ -1,6 +1,7 @@ package com.songoda.core.nms.v1_9_R1; import com.songoda.core.nms.CustomAnvil; +import com.songoda.core.nms.methods.AnvilTextChange; import java.lang.reflect.Field; import java.util.logging.Level; import java.util.logging.Logger; @@ -24,6 +25,7 @@ public class AnvilView extends ContainerAnvil implements CustomAnvil { private String title = "Repairing"; private int cost = -1; private boolean canUse = true; + private AnvilTextChange textChange = null; // used for setting custom inventory static Field mc_ContainerAnvil_repairInventory; // subcontainer with only the result @@ -93,6 +95,11 @@ public class AnvilView extends ContainerAnvil implements CustomAnvil { } } + @Override + public void update() { + e(); + } + @Override public String getRenameText() { try { @@ -109,6 +116,11 @@ public class AnvilView extends ContainerAnvil implements CustomAnvil { this.a(text); } + @Override + public void setOnChange(AnvilTextChange handler) { + textChange = handler; + } + @Override public String getCustomTitle() { return title; diff --git a/NMS/NMS-v1_9_R2/src/com/songoda/core/nms/v1_9_R2/AnvilView.java b/NMS/NMS-v1_9_R2/src/com/songoda/core/nms/v1_9_R2/AnvilView.java index 76c1390f..4006628e 100644 --- a/NMS/NMS-v1_9_R2/src/com/songoda/core/nms/v1_9_R2/AnvilView.java +++ b/NMS/NMS-v1_9_R2/src/com/songoda/core/nms/v1_9_R2/AnvilView.java @@ -1,6 +1,7 @@ package com.songoda.core.nms.v1_9_R2; import com.songoda.core.nms.CustomAnvil; +import com.songoda.core.nms.methods.AnvilTextChange; import java.lang.reflect.Field; import java.util.logging.Level; import java.util.logging.Logger; @@ -24,6 +25,7 @@ public class AnvilView extends ContainerAnvil implements CustomAnvil { private String title = "Repairing"; private int cost = -1; private boolean canUse = true; + private AnvilTextChange textChange = null; // used for setting custom inventory static Field mc_ContainerAnvil_repairInventory; // subcontainer with only the result @@ -93,6 +95,11 @@ public class AnvilView extends ContainerAnvil implements CustomAnvil { } } + @Override + public void update() { + e(); + } + @Override public String getRenameText() { try { @@ -109,6 +116,11 @@ public class AnvilView extends ContainerAnvil implements CustomAnvil { this.a(text); } + @Override + public void setOnChange(AnvilTextChange handler) { + textChange = handler; + } + @Override public String getCustomTitle() { return title; From 24948cf44b7c66da19659d2e5a0161468ad67574 Mon Sep 17 00:00:00 2001 From: jascotty2 Date: Mon, 7 Oct 2019 14:22:28 -0500 Subject: [PATCH 10/21] add WG region list hooks --- .../songoda/core/hooks/WorldGuardHook.java | 40 ++- .../worldguard/WorldGuardRegionHandler.java | 248 ++++++++++++++++++ 2 files changed, 285 insertions(+), 3 deletions(-) create mode 100644 Core/src/main/java/com/songoda/core/hooks/worldguard/WorldGuardRegionHandler.java diff --git a/Core/src/main/java/com/songoda/core/hooks/WorldGuardHook.java b/Core/src/main/java/com/songoda/core/hooks/WorldGuardHook.java index 05bd5f06..cd94eff6 100644 --- a/Core/src/main/java/com/songoda/core/hooks/WorldGuardHook.java +++ b/Core/src/main/java/com/songoda/core/hooks/WorldGuardHook.java @@ -1,8 +1,14 @@ package com.songoda.core.hooks; import com.songoda.core.hooks.worldguard.WorldGuardFlagHandler; +import com.songoda.core.hooks.worldguard.WorldGuardRegionHandler; +import java.util.Collections; +import java.util.List; +import java.util.Objects; import org.bukkit.Chunk; import org.bukkit.Location; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; public class WorldGuardHook { @@ -24,7 +30,7 @@ public class WorldGuardHook { * @param flag name of the flag to set * @param state default value of the flag */ - public static void addHook(String flag, boolean state) { + public static void addHook(@NotNull String flag, boolean state) { if(canHook) { WorldGuardFlagHandler.addHook(flag, state); } @@ -47,7 +53,8 @@ public class WorldGuardHook { * @param flag ALLOW/DENY flag to check * @return flag state, or null if undefined */ - public static Boolean getBooleanFlag(Location l, String flag) { + @Nullable + public static Boolean getBooleanFlag(@NotNull Location l, @NotNull String flag) { return canHook ? WorldGuardFlagHandler.getBooleanFlag(l, flag) : null; } @@ -58,7 +65,34 @@ public class WorldGuardHook { * @param flag ALLOW/DENY flag to check * @return flag state, or null if undefined */ - public static Boolean getBooleanFlag(Chunk c, String flag) { + @Nullable + public static Boolean getBooleanFlag(@NotNull Chunk c, @NotNull String flag) { return canHook ? WorldGuardFlagHandler.getBooleanFlag(c, flag) : null; } + + public static boolean isPvpAllowed(@NotNull Location loc) { + return canHook ? Objects.equals(WorldGuardFlagHandler.getBooleanFlag(loc, "pvp"), Boolean.TRUE) : false; + } + + public boolean isBreakAllowed(@NotNull Location loc) { + return canHook ? Objects.equals(WorldGuardFlagHandler.getBooleanFlag(loc, "block-break"), Boolean.TRUE) : false; + } + + public boolean isExplosionsAllowed(@NotNull Location loc) { + return canHook ? Objects.equals(WorldGuardFlagHandler.getBooleanFlag(loc, "other-explosion"), Boolean.TRUE) : false; + } + + public boolean isMobSpawningAllowed(@NotNull Location loc) { + return canHook ? Objects.equals(WorldGuardFlagHandler.getBooleanFlag(loc, "mob-spawning"), Boolean.TRUE) : false; + } + + @NotNull + public static List getRegionNames(@NotNull Location loc) { + return canHook ? WorldGuardRegionHandler.getRegionNames(loc) : Collections.EMPTY_LIST; + } + + @NotNull + public static List getRegionNames(@NotNull Chunk c) { + return canHook ? WorldGuardRegionHandler.getRegionNames(c) : Collections.EMPTY_LIST; + } } diff --git a/Core/src/main/java/com/songoda/core/hooks/worldguard/WorldGuardRegionHandler.java b/Core/src/main/java/com/songoda/core/hooks/worldguard/WorldGuardRegionHandler.java new file mode 100644 index 00000000..4176e57c --- /dev/null +++ b/Core/src/main/java/com/songoda/core/hooks/worldguard/WorldGuardRegionHandler.java @@ -0,0 +1,248 @@ +package com.songoda.core.hooks.worldguard; + +import com.sk89q.worldedit.bukkit.BukkitAdapter; +import com.sk89q.worldedit.math.BlockVector3; +import com.sk89q.worldguard.WorldGuard; +import com.sk89q.worldguard.protection.ApplicableRegionSet; +import com.sk89q.worldguard.protection.managers.RegionManager; +import com.sk89q.worldguard.protection.regions.ProtectedCuboidRegion; +import com.sk89q.worldguard.protection.regions.ProtectedRegion; +import java.lang.reflect.Constructor; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.logging.Level; +import org.bukkit.Bukkit; +import org.bukkit.Chunk; +import org.bukkit.Location; + +public class WorldGuardRegionHandler { + + static boolean wgPlugin; + static Object worldGuardPlugin; + static boolean wg_v7 = false; + static boolean legacy_v60 = false; + static boolean legacy_v62 = false; + static boolean legacy_v5 = false; + static Method legacy_getRegionManager = null; + static Method legacy_getApplicableRegions_Region = null; + static Method legacy_getApplicableRegions_Location = null; + static Constructor legacy_newProtectedCuboidRegion; + static Class legacy_blockVectorClazz; + static Constructor legacy_newblockVector; + static Class legacy_VectorClazz; + static Constructor legacy_newVectorClazz; + static Method legacy_getApplicableRegions_Vector = null; + + static void init() { + if ((wgPlugin = (worldGuardPlugin = Bukkit.getPluginManager().getPlugin("WorldGuard")) != null)) { + // a number of flags were introduced in 7.x that aren't in 5 or 6 + try { + // if this class exists, we're on 7.x + Class.forName("com.sk89q.worldguard.protection.flags.WeatherTypeFlag"); + wg_v7 = true; + } catch (ClassNotFoundException ex) { + try { + // if this class exists, we're on 6.2 + Class.forName("com.sk89q.worldguard.protection.flags.registry.SimpleFlagRegistry"); + legacy_v62 = true; + } catch (ClassNotFoundException ex2) { + try { + // if this class exists, we're on 6.0 + Class.forName("com.sk89q.worldguard.protection.flags.BuildFlag"); + legacy_v60 = true; + } catch (ClassNotFoundException ex3) { + try { + // if this class exists, we're on 5.x + Class.forName("com.sk89q.worldguard.protection.flags.DefaultFlag"); + legacy_v5 = true; + } catch (ClassNotFoundException ex4) { + // ¯\_(ツ)_/¯ + wgPlugin = false; + } + } + } + } + } + if (wgPlugin && (legacy_v62 || legacy_v60 || legacy_v5)) { + try { + // cache reflection methods + if (legacy_getRegionManager == null) { + legacy_getRegionManager = worldGuardPlugin.getClass() + .getDeclaredMethod("getRegionManager", org.bukkit.World.class); + legacy_getApplicableRegions_Region = RegionManager.class.getDeclaredMethod("getApplicableRegions", + Class.forName("com.sk89q.worldguard.protection.regions.ProtectedRegion")); + legacy_getApplicableRegions_Location = RegionManager.class.getDeclaredMethod("getApplicableRegions", + Location.class); + legacy_blockVectorClazz = Class.forName("com.sk89q.worldedit.BlockVector"); + legacy_newblockVector = legacy_blockVectorClazz.getConstructor(int.class, int.class, int.class); + legacy_newProtectedCuboidRegion = Class.forName("com.sk89q.worldguard.protection.regions.ProtectedCuboidRegion") + .getConstructor(String.class, legacy_blockVectorClazz, legacy_blockVectorClazz); + legacy_VectorClazz = Class.forName("com.sk89q.worldedit.Vector"); + legacy_newVectorClazz = legacy_VectorClazz.getConstructor(int.class, int.class, int.class); + legacy_getApplicableRegions_Vector = RegionManager.class.getDeclaredMethod("getApplicableRegions", legacy_VectorClazz); + } + } catch (Exception ex) { + //Bukkit.getServer().getLogger().log(Level.WARNING, "Failed to set legacy WorldGuard Flags", ex); + Bukkit.getServer().getLogger().log(Level.WARNING, "Could not load WorldGuard methods for " + (legacy_v62 ? "6.2" : (legacy_v60 ? "6.0" : "5"))); + wgPlugin = false; + } + } + } + + public static List getRegionNames(Chunk c) { + if (worldGuardPlugin == null) { + init(); + } + if (!wgPlugin || c == null) { + return Collections.EMPTY_LIST; + } else if (legacy_v62 || legacy_v60 || legacy_v5) { + return getRegionNamesLegacy(c); + } + + RegionManager worldManager = WorldGuard.getInstance().getPlatform().getRegionContainer().get(BukkitAdapter.adapt(c.getWorld())); + if (worldManager == null) { + return Collections.EMPTY_LIST; + } + ProtectedCuboidRegion chunkRegion = new ProtectedCuboidRegion("__TEST__", + BlockVector3.at(c.getX() << 4, c.getWorld().getMaxHeight(), c.getZ() << 4), + BlockVector3.at((c.getX() << 4) + 15, 0, (c.getZ() << 4) + 15)); + ApplicableRegionSet set = worldManager.getApplicableRegions(chunkRegion); + + List regions = new ArrayList<>(); + List parentNames = new ArrayList<>(); + + for (ProtectedRegion region : set) { + String id = region.getId(); + + regions.add(id); + + ProtectedRegion parent = region.getParent(); + + while (parent != null) { + parentNames.add(parent.getId()); + parent = parent.getParent(); + } + } + regions.removeAll(parentNames); + + return regions; + } + + private static List getRegionNamesLegacy(Chunk c) { + try { + // grab the applicable manager for this world + Object worldManager = (RegionManager) legacy_getRegionManager.invoke(worldGuardPlugin, c.getWorld()); + if (worldManager == null) { + return null; + } + // Create a legacy ProtectedCuboidRegion + Object chunkRegion = legacy_newProtectedCuboidRegion.newInstance("__TEST__", + legacy_newblockVector.newInstance(c.getX() << 4, c.getWorld().getMaxHeight(), c.getZ() << 4), + legacy_newblockVector.newInstance((c.getX() << 4) + 15, 0, (c.getZ() << 4) + 15)); + + // now look for any intersecting regions + // ApplicableRegionSet's prototype is different from v5 to v6, but they're both Iterable + Iterable set = (Iterable) legacy_getApplicableRegions_Region.invoke(worldManager, chunkRegion); + + List regions = new ArrayList<>(); + List parentNames = new ArrayList<>(); + + for (ProtectedRegion region : set) { + String id = region.getId(); + + regions.add(id); + + ProtectedRegion parent = region.getParent(); + + while (parent != null) { + parentNames.add(parent.getId()); + parent = parent.getParent(); + } + } + regions.removeAll(parentNames); + + return regions; + } catch (Exception ex) { + Bukkit.getServer().getLogger().log(Level.WARNING, "Could not grab regions from WorldGuard", ex); + } + return Collections.EMPTY_LIST; + } + + public static List getRegionNames(Location loc) { + if (worldGuardPlugin == null) { + init(); + } + if (!wgPlugin || loc == null) { + return Collections.EMPTY_LIST; + } else if (legacy_v62 || legacy_v60 || legacy_v5) { + return getRegionNamesLegacy(loc); + } + + RegionManager regionManager = WorldGuard.getInstance().getPlatform().getRegionContainer().get(BukkitAdapter.adapt(loc.getWorld())); + + if (regionManager == null) { + return Collections.EMPTY_LIST; + } + + List regions = new ArrayList<>(); + List parentNames = new ArrayList<>(); + ApplicableRegionSet set = regionManager.getApplicableRegions(BukkitAdapter.asBlockVector(loc)); + + for (ProtectedRegion region : set) { + String id = region.getId(); + + regions.add(id); + + ProtectedRegion parent = region.getParent(); + + while (parent != null) { + parentNames.add(parent.getId()); + parent = parent.getParent(); + } + } + regions.removeAll(parentNames); + + return regions; + + } + + private static List getRegionNamesLegacy(Location loc) { + try { + // grab the applicable manager for this world + Object worldManager = (RegionManager) legacy_getRegionManager.invoke(worldGuardPlugin, loc.getWorld()); + if (worldManager == null) { + return Collections.EMPTY_LIST; + } + + // create a vector object + Object vec = legacy_newVectorClazz.newInstance(loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()); + // now look for any intersecting regions + // ApplicableRegionSet's prototype is different from v5 to v6, but they're both Iterable + Iterable set = (Iterable) legacy_getApplicableRegions_Vector.invoke(worldManager, legacy_VectorClazz.cast(vec)); + + List regions = new ArrayList<>(); + List parentNames = new ArrayList<>(); + + for (ProtectedRegion region : set) { + String id = region.getId(); + + regions.add(id); + + ProtectedRegion parent = region.getParent(); + + while (parent != null) { + parentNames.add(parent.getId()); + parent = parent.getParent(); + } + } + regions.removeAll(parentNames); + + return regions; + } catch (Exception ex) { + Bukkit.getServer().getLogger().log(Level.WARNING, "Could not grab regions from WorldGuard", ex); + } + return Collections.EMPTY_LIST; + } +} From acdbd82e32e7510c87db3293eeddc42e23fe3208 Mon Sep 17 00:00:00 2001 From: jascotty2 Date: Mon, 7 Oct 2019 16:38:20 -0500 Subject: [PATCH 11/21] load flags even when not registering custom flags --- .../songoda/core/configuration/Config.java | 4 +- .../worldguard/WorldGuardFlagHandler.java | 97 +++++++++++++------ 2 files changed, 67 insertions(+), 34 deletions(-) diff --git a/Core/src/main/java/com/songoda/core/configuration/Config.java b/Core/src/main/java/com/songoda/core/configuration/Config.java index ce620256..1cf164e7 100644 --- a/Core/src/main/java/com/songoda/core/configuration/Config.java +++ b/Core/src/main/java/com/songoda/core/configuration/Config.java @@ -87,9 +87,8 @@ public class Config extends ConfigSection { boolean autoremove = false; /** * load comments when loading the file - * TODO */ - boolean loadComments = false; + boolean loadComments = true; /** * Default comment applied to config nodes */ @@ -440,7 +439,6 @@ public class Config extends ConfigSection { } protected void parseComments(@NotNull String contents, @NotNull Map input) { - // TODO? // if starts with a comment, load all nonbreaking comments as a header // then load all comments and assign to the next valid node loaded // (Only load comments that are on their own line) diff --git a/Core/src/main/java/com/songoda/core/hooks/worldguard/WorldGuardFlagHandler.java b/Core/src/main/java/com/songoda/core/hooks/worldguard/WorldGuardFlagHandler.java index 0cff57d8..5b4c8ed5 100644 --- a/Core/src/main/java/com/songoda/core/hooks/worldguard/WorldGuardFlagHandler.java +++ b/Core/src/main/java/com/songoda/core/hooks/worldguard/WorldGuardFlagHandler.java @@ -19,6 +19,7 @@ import java.lang.reflect.Modifier; import java.util.HashMap; import java.util.Map; import java.util.logging.Level; +import java.util.logging.Logger; import java.util.stream.Stream; import org.bukkit.Bukkit; import org.bukkit.Chunk; @@ -31,7 +32,7 @@ import org.bukkit.Location; */ public class WorldGuardFlagHandler { - static Boolean wgPlugin = null; + static boolean wgPlugin; static Object worldGuardPlugin; static boolean wg_v7 = false; static boolean legacy_v60 = false; @@ -40,15 +41,8 @@ public class WorldGuardFlagHandler { static boolean hooksInstalled = false; static Map flags = new HashMap(); - /** - * Attempt to register a worldGuard flag (ALLOW/DENY)
- * Note: This must be called before WorldGuard loads, or it will fail. - * - * @param flag name of the flag to set - * @param state default value of the flag - */ - public static void addHook(String flag, boolean state) { - if (wgPlugin == null && (wgPlugin = (worldGuardPlugin = Bukkit.getPluginManager().getPlugin("WorldGuard")) != null)) { + static { + if ((wgPlugin = (worldGuardPlugin = Bukkit.getPluginManager().getPlugin("WorldGuard")) != null)) { // a number of flags were introduced in 7.x that aren't in 5 or 6 try { // if this class exists, we're on 7.x @@ -77,6 +71,16 @@ public class WorldGuardFlagHandler { } } } + } + + /** + * Attempt to register a worldGuard flag (ALLOW/DENY)
+ * Note: This must be called before WorldGuard loads, or it will fail. + * + * @param flag name of the flag to set + * @param state default value of the flag + */ + public static void addHook(String flag, boolean state) { if (!wgPlugin) { return; } @@ -135,12 +139,14 @@ public class WorldGuardFlagHandler { // and put the new list into place setStaticField(flagField, flagsNew); - if (legacy_v62) { // SimpleFlagRegistry is NOT in 6.0 + if (legacy_v62) { // SimpleFlagRegistry is NOT in 6.0 or 6.1 // register this flag in the registry - Object flagRegistry = getPrivateField(worldGuardPlugin.getClass(), worldGuardPlugin, "flagRegistry"); - Class simpleFlagRegistryClazz = Class.forName("com.sk89q.worldguard.protection.flags.registry.SimpleFlagRegistry"); - Method registerSimpleFlagRegistry = simpleFlagRegistryClazz.getDeclaredMethod("register", Flag.class); - registerSimpleFlagRegistry.invoke(flagRegistry, wgFlag); + if(legacy_simpleFlagRegistryClazz == null) { + legacy_worldGuardPlugin_flagRegistry = getPrivateField(worldGuardPlugin.getClass(), worldGuardPlugin, "flagRegistry"); + legacy_simpleFlagRegistryClazz = Class.forName("com.sk89q.worldguard.protection.flags.registry.SimpleFlagRegistry"); + legacy_simpleFlagRegistry_get = legacy_simpleFlagRegistryClazz.getDeclaredMethod("get", String.class); + } + legacy_simpleFlagRegistryClazz.getDeclaredMethod("register", Flag.class).invoke(legacy_worldGuardPlugin_flagRegistry, wgFlag); } // all good! @@ -168,7 +174,41 @@ public class WorldGuardFlagHandler { } public static boolean isEnabled() { - return wgPlugin != null && wgPlugin; + return wgPlugin; + } + + public static Object getFlag(String flag) { + Object flagObj = flags.get(flag); + + // load a flag if we don't know it + if (flagObj == null) { + if (wg_v7) { + flags.put(flag, flagObj = WorldGuard.getInstance().getFlagRegistry().get(flag)); + } else if (legacy_v62) { + try { + if (legacy_simpleFlagRegistryClazz == null) { + legacy_worldGuardPlugin_flagRegistry = getPrivateField(worldGuardPlugin.getClass(), worldGuardPlugin, "flagRegistry"); + legacy_simpleFlagRegistryClazz = Class.forName("com.sk89q.worldguard.protection.flags.registry.SimpleFlagRegistry"); + legacy_simpleFlagRegistry_get = legacy_simpleFlagRegistryClazz.getDeclaredMethod("get", String.class); + } + flags.put(flag, flagObj = legacy_simpleFlagRegistry_get.invoke(legacy_worldGuardPlugin_flagRegistry, flag)); + } catch (Exception ex) { + Bukkit.getServer().getLogger().log(Level.WARNING, "Could not grab flags from WorldGuard", ex); + } + } else if (!legacy_loadedFlags && (legacy_v60 || legacy_v5)) { + try { + Class defaultFlagClazz = Class.forName("com.sk89q.worldguard.protection.flags.DefaultFlag"); + Field flagField = defaultFlagClazz.getField("flagsList"); + Flag[] flagsOld = (Flag[]) flagField.get(null); + Stream.of(flagsOld).forEach(f -> flags.put(f.getName(), f)); + flagObj = flags.get(flag); + } catch (Exception ex) { + Bukkit.getServer().getLogger().log(Level.WARNING, "Could not grab flags from WorldGuard", ex); + } + legacy_loadedFlags = true; + } + } + return flagObj; } /** @@ -179,20 +219,16 @@ public class WorldGuardFlagHandler { * @return flag state, or null if undefined */ public static Boolean getBooleanFlag(Location l, String flag) { - if (wgPlugin == null || !wgPlugin) { + if (!wgPlugin) { return null; } - Object flagObj = flags.get(flag); + Object flagObj = getFlag(flag); + // There's a different way to get this in the old version if (legacy_v62 || legacy_v60 || legacy_v5) { return flagObj == null ? null : getBooleanFlagLegacy(l, flagObj); } - // for convinience, we can load a flag if we don't know it - if (flagObj == null) { - flags.put(flag, flagObj = WorldGuard.getInstance().getFlagRegistry().get(flag)); - } - // so, what's up? if (flagObj instanceof StateFlag) { RegionContainer container = WorldGuard.getInstance().getPlatform().getRegionContainer(); @@ -211,20 +247,15 @@ public class WorldGuardFlagHandler { * @return flag state, or null if undefined */ public static Boolean getBooleanFlag(Chunk c, String flag) { - if (wgPlugin == null || !wgPlugin) { + if (!wgPlugin) { return null; } - Object flagObj = flags.get(flag); + Object flagObj = getFlag(flag); // There's a different way to get this in the old version if (legacy_v62 || legacy_v60 || legacy_v5) { return flagObj == null ? null : getBooleanFlagLegacy(c, flagObj); } - // for convinience, we can load a flag if we don't know it - if (flagObj == null) { - flags.put(flag, flagObj = WorldGuard.getInstance().getFlagRegistry().get(flag)); - } - // so, what's up? if (flagObj instanceof StateFlag) { RegionManager worldManager = WorldGuard.getInstance().getPlatform().getRegionContainer().get(BukkitAdapter.adapt(c.getWorld())); @@ -254,6 +285,10 @@ public class WorldGuardFlagHandler { static Class legacy_VectorClazz; static Constructor legacy_newVectorClazz; static Method legacy_getApplicableRegions_Vector = null; + static Class legacy_simpleFlagRegistryClazz = null; // only used for 6.2 + static Method legacy_simpleFlagRegistry_get = null; // only used for 6.2 + static Object legacy_worldGuardPlugin_flagRegistry = null; // only used for 6.2 + static boolean legacy_loadedFlags = false; private static Boolean getBooleanFlagLegacy(Location l, Object flag) { try { @@ -294,7 +329,7 @@ public class WorldGuardFlagHandler { // also doesn't have a "queryState" function //getFlag(T flag) if (legacy5_applicableRegionSet_getFlag == null) { - legacy5_applicableRegionSet_getFlag = Class.forName("com.sk89q.worldguard.protection.ApplicableRegionSet").getMethod("getFlag", Object.class); + legacy5_applicableRegionSet_getFlag = Class.forName("com.sk89q.worldguard.protection.ApplicableRegionSet").getMethod("getFlag", Flag.class); } result = (State) legacy5_applicableRegionSet_getFlag.invoke(set, flag); } From 9fe7f1ac9e0fe3db647800bc8341fff6acd21608 Mon Sep 17 00:00:00 2001 From: jascotty2 Date: Mon, 7 Oct 2019 17:12:12 -0500 Subject: [PATCH 12/21] null flag support for wg7 --- .../songoda/core/hooks/WorldGuardHook.java | 32 +++++++++++++++++++ .../worldguard/WorldGuardFlagHandler.java | 15 ++++----- 2 files changed, 39 insertions(+), 8 deletions(-) diff --git a/Core/src/main/java/com/songoda/core/hooks/WorldGuardHook.java b/Core/src/main/java/com/songoda/core/hooks/WorldGuardHook.java index cd94eff6..0e56f977 100644 --- a/Core/src/main/java/com/songoda/core/hooks/WorldGuardHook.java +++ b/Core/src/main/java/com/songoda/core/hooks/WorldGuardHook.java @@ -70,27 +70,59 @@ public class WorldGuardHook { return canHook ? WorldGuardFlagHandler.getBooleanFlag(c, flag) : null; } + /** + * Check to see if the pvp flag is set and is set to ALLOW + * + * @param loc Location to check + * @return false if the pvp flag is not set for this region, or is set to DENY + */ public static boolean isPvpAllowed(@NotNull Location loc) { return canHook ? Objects.equals(WorldGuardFlagHandler.getBooleanFlag(loc, "pvp"), Boolean.TRUE) : false; } + /** + * Check to see if the block-break flag is set and is set to ALLOW + * + * @param loc Location to check + * @return false if the block-break flag is not set for this region, or is set to DENY + */ public boolean isBreakAllowed(@NotNull Location loc) { return canHook ? Objects.equals(WorldGuardFlagHandler.getBooleanFlag(loc, "block-break"), Boolean.TRUE) : false; } + /** + * Check to see if the other-explosion flag is set and is set to ALLOW + * + * @param loc Location to check + * @return false if the other-explosion flag is not set for this region, or is set to DENY + */ public boolean isExplosionsAllowed(@NotNull Location loc) { return canHook ? Objects.equals(WorldGuardFlagHandler.getBooleanFlag(loc, "other-explosion"), Boolean.TRUE) : false; } + /** + * Check to see if the mob-spawning flag is set and is set to ALLOW + * + * @param loc Location to check + * @return false if the mob-spawning flag is not set for this region, or is set to DENY + */ public boolean isMobSpawningAllowed(@NotNull Location loc) { return canHook ? Objects.equals(WorldGuardFlagHandler.getBooleanFlag(loc, "mob-spawning"), Boolean.TRUE) : false; } + /** + * @param loc Location to check + * @return A list of regions that contain this location. + */ @NotNull public static List getRegionNames(@NotNull Location loc) { return canHook ? WorldGuardRegionHandler.getRegionNames(loc) : Collections.EMPTY_LIST; } + /** + * @param c Chunk to check + * @return A list of regions that contain any part of this chunk. + */ @NotNull public static List getRegionNames(@NotNull Chunk c) { return canHook ? WorldGuardRegionHandler.getRegionNames(c) : Collections.EMPTY_LIST; diff --git a/Core/src/main/java/com/songoda/core/hooks/worldguard/WorldGuardFlagHandler.java b/Core/src/main/java/com/songoda/core/hooks/worldguard/WorldGuardFlagHandler.java index 5b4c8ed5..849956a0 100644 --- a/Core/src/main/java/com/songoda/core/hooks/worldguard/WorldGuardFlagHandler.java +++ b/Core/src/main/java/com/songoda/core/hooks/worldguard/WorldGuardFlagHandler.java @@ -19,7 +19,6 @@ import java.lang.reflect.Modifier; import java.util.HashMap; import java.util.Map; import java.util.logging.Level; -import java.util.logging.Logger; import java.util.stream.Stream; import org.bukkit.Bukkit; import org.bukkit.Chunk; @@ -214,11 +213,11 @@ public class WorldGuardFlagHandler { /** * Checks this location to see what this flag is set to * - * @param l location to check + * @param loc location to check * @param flag ALLOW/DENY flag to check * @return flag state, or null if undefined */ - public static Boolean getBooleanFlag(Location l, String flag) { + public static Boolean getBooleanFlag(Location loc, String flag) { if (!wgPlugin) { return null; } @@ -226,15 +225,15 @@ public class WorldGuardFlagHandler { // There's a different way to get this in the old version if (legacy_v62 || legacy_v60 || legacy_v5) { - return flagObj == null ? null : getBooleanFlagLegacy(l, flagObj); + return flagObj == null ? null : getBooleanFlagLegacy(loc, flagObj); } // so, what's up? if (flagObj instanceof StateFlag) { - RegionContainer container = WorldGuard.getInstance().getPlatform().getRegionContainer(); - RegionQuery query = container.createQuery(); - com.sk89q.worldedit.util.Location loc = BukkitAdapter.adapt(l); - return query.testState(loc, (RegionAssociable) null, (StateFlag) flagObj); + RegionQuery query = WorldGuard.getInstance().getPlatform().getRegionContainer().createQuery(); + //return query.testState(BukkitAdapter.adapt(loc), (RegionAssociable) null, (StateFlag) flagObj); + State result = query.getApplicableRegions(BukkitAdapter.adapt(loc)).queryState(null, (StateFlag) flagObj); + return result != null ? result == State.ALLOW : null; } return null; } From 1f8f859d78b55237c2fa2e7a30af41127a29be72 Mon Sep 17 00:00:00 2001 From: jascotty2 Date: Mon, 7 Oct 2019 20:29:42 -0500 Subject: [PATCH 13/21] two-argument existence should not force all to be double --- .../main/java/com/songoda/core/commands/CommandManager.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Core/src/main/java/com/songoda/core/commands/CommandManager.java b/Core/src/main/java/com/songoda/core/commands/CommandManager.java index cc7e538d..35039025 100644 --- a/Core/src/main/java/com/songoda/core/commands/CommandManager.java +++ b/Core/src/main/java/com/songoda/core/commands/CommandManager.java @@ -149,9 +149,9 @@ public class CommandManager implements CommandExecutor, TabCompleter { String match = null; // support for two-argument subcommands if(args.length >= 2 && nested.children.keySet().stream().anyMatch(k -> k.indexOf(' ') != -1)) { - cmd = String.join(" ", args[0], args[1]); - if(nested.children.containsKey(cmd)) - return cmd; + String cmd2 = String.join(" ", args[0], args[1]); + if(nested.children.containsKey(cmd2)) + return cmd2; } // if we don't have a subcommand, should we search for one? if (allowLooseCommands) { From 8c2728f24942efe1f5220f7eea1f9abd522e0709 Mon Sep 17 00:00:00 2001 From: jascotty2 Date: Tue, 8 Oct 2019 10:56:53 -0500 Subject: [PATCH 14/21] command support for custom messages, default help command, multilevel nested commands --- .../core/commands/AbstractCommand.java | 46 ++++-- .../songoda/core/commands/CommandManager.java | 151 ++++++++++++------ .../songoda/core/commands/MainCommand.java | 117 ++++++++++++++ .../core/commands/SimpleNestedCommand.java | 4 +- 4 files changed, 255 insertions(+), 63 deletions(-) create mode 100644 Core/src/main/java/com/songoda/core/commands/MainCommand.java diff --git a/Core/src/main/java/com/songoda/core/commands/AbstractCommand.java b/Core/src/main/java/com/songoda/core/commands/AbstractCommand.java index e72ea9a1..52341172 100644 --- a/Core/src/main/java/com/songoda/core/commands/AbstractCommand.java +++ b/Core/src/main/java/com/songoda/core/commands/AbstractCommand.java @@ -9,29 +9,42 @@ import java.util.List; public abstract class AbstractCommand { - private final boolean noConsole; - private boolean hasArgs = false; + private final CommandType _cmdType; + private final boolean _hasArgs; + private final List _handledCommands = new ArrayList<>(); - private final List subCommand = new ArrayList<>(); - - protected AbstractCommand(boolean noConsole, String... command) { - this.subCommand.addAll(Arrays.asList(command)); - this.noConsole = noConsole; + protected AbstractCommand(CommandType type, String... command) { + this._handledCommands.addAll(Arrays.asList(command)); + this._hasArgs = false; + this._cmdType = type; } - protected AbstractCommand(boolean noConsole, boolean hasArgs, String... command) { - this.subCommand.addAll(Arrays.asList(command)); + protected AbstractCommand(CommandType type, boolean hasArgs, String... command) { + this._handledCommands.addAll(Arrays.asList(command)); + this._hasArgs = hasArgs; + this._cmdType = type; + } - this.hasArgs = hasArgs; - this.noConsole = noConsole; + @Deprecated + protected AbstractCommand(boolean noConsole, String... command) { + this._handledCommands.addAll(Arrays.asList(command)); + this._hasArgs = false; + this._cmdType = noConsole ? CommandType.PLAYER_ONLY : CommandType.CONSOLE_OK; + } + + @Deprecated + protected AbstractCommand(boolean noConsole, boolean hasArgs, String... command) { + this._handledCommands.addAll(Arrays.asList(command)); + this._hasArgs = hasArgs; + this._cmdType = noConsole ? CommandType.PLAYER_ONLY : CommandType.CONSOLE_OK; } public final List getCommands() { - return Collections.unmodifiableList(subCommand); + return Collections.unmodifiableList(_handledCommands); } public final void addSubCommand(String command) { - subCommand.add(command); + _handledCommands.add(command); } protected abstract ReturnType runCommand(CommandSender sender, String... args); @@ -45,13 +58,14 @@ public abstract class AbstractCommand { public abstract String getDescription(); public boolean hasArgs() { - return hasArgs; + return _hasArgs; } public boolean isNoConsole() { - return noConsole; + return _cmdType == CommandType.PLAYER_ONLY; } - public static enum ReturnType {SUCCESS, FAILURE, SYNTAX_ERROR} + public static enum ReturnType {SUCCESS, NEEDS_PLAYER, FAILURE, SYNTAX_ERROR} + public static enum CommandType {PLAYER_ONLY, CONSOLE_OK} } diff --git a/Core/src/main/java/com/songoda/core/commands/CommandManager.java b/Core/src/main/java/com/songoda/core/commands/CommandManager.java index 35039025..95f8d243 100644 --- a/Core/src/main/java/com/songoda/core/commands/CommandManager.java +++ b/Core/src/main/java/com/songoda/core/commands/CommandManager.java @@ -2,17 +2,9 @@ package com.songoda.core.commands; import com.songoda.core.compatibility.ServerProject; import com.songoda.core.compatibility.ServerVersion; -import com.songoda.core.utils.TextUtils; import java.lang.reflect.Constructor; import java.lang.reflect.Field; -import org.bukkit.command.Command; -import org.bukkit.command.CommandExecutor; -import org.bukkit.command.CommandSender; -import org.bukkit.command.PluginCommand; -import org.bukkit.command.TabCompleter; -import org.bukkit.entity.Player; -import org.bukkit.plugin.java.JavaPlugin; - +import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; @@ -21,20 +13,52 @@ import java.util.Map; import java.util.Set; import java.util.stream.Collectors; import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.command.PluginCommand; import org.bukkit.command.SimpleCommandMap; +import org.bukkit.command.TabCompleter; +import org.bukkit.entity.Player; import org.bukkit.plugin.Plugin; +import org.bukkit.plugin.java.JavaPlugin; public class CommandManager implements CommandExecutor, TabCompleter { private final JavaPlugin plugin; private final HashMap commands = new HashMap<>(); + private String msg_noConsole = ChatColor.RED + "You must be a player to use this command."; + private String msg_noPerms = ChatColor.RED + "You do not have permission to do that."; + private String msg_noCommand = ChatColor.GRAY + "The command you entered does not exist or is spelt incorrectly."; + private List msg_syntaxError = Arrays.asList( + ChatColor.RED + "Invalid Syntax!", + ChatColor.GRAY + "The valid syntax is: " + ChatColor.GOLD + "%syntax%" + ChatColor.GRAY + "." + ); + private boolean allowLooseCommands = false; public CommandManager(JavaPlugin plugin) { this.plugin = plugin; } + public void setNoConsoleMessage(String msg_noConsole) { + this.msg_noConsole = msg_noConsole; + } + + public void setNoPermsMessage(String msg_noPerms) { + this.msg_noPerms = msg_noPerms; + } + + public void setNoCommandMessage(String msg_noCommand) { + this.msg_noCommand = msg_noCommand; + } + + public void setSyntaxErrorMessage(List msg_syntaxError) { + this.msg_syntaxError = msg_syntaxError; + } + public Set getCommands() { return Collections.unmodifiableSet(commands.keySet()); } @@ -51,8 +75,8 @@ public class CommandManager implements CommandExecutor, TabCompleter { .forEach(c -> { all.add(c.parent); c.children.values().stream() - .filter(s -> !all.contains(s)) - .forEach(s -> all.add(s)); + .filter(s -> !all.contains(s)) + .forEach(s -> all.add(s)); }); return all; } @@ -62,16 +86,13 @@ public class CommandManager implements CommandExecutor, TabCompleter { return this; } - /** - * TODO: Test compatibility. Seems to fail in 1.8 - */ public SimpleNestedCommand registerCommandDynamically(AbstractCommand abstractCommand) { SimpleNestedCommand nested = new SimpleNestedCommand(abstractCommand); abstractCommand.getCommands().stream().forEach(cmd -> { CommandManager.registerCommandDynamically(plugin, cmd, this, this); commands.put(cmd.toLowerCase(), nested); PluginCommand pcmd = plugin.getCommand(cmd); - if(pcmd != null) { + if (pcmd != null) { pcmd.setExecutor(this); pcmd.setTabCompleter(this); } else { @@ -86,7 +107,7 @@ public class CommandManager implements CommandExecutor, TabCompleter { abstractCommand.getCommands().stream().forEach(cmd -> { commands.put(cmd.toLowerCase(), nested); PluginCommand pcmd = plugin.getCommand(cmd); - if(pcmd != null) { + if (pcmd != null) { pcmd.setExecutor(this); pcmd.setTabCompleter(this); } else { @@ -96,14 +117,43 @@ public class CommandManager implements CommandExecutor, TabCompleter { return nested; } + public MainCommand addMainCommand(String command) { + MainCommand nested = new MainCommand(plugin, command); + commands.put(command.toLowerCase(), nested.nestedCommands); + + PluginCommand pcmd = plugin.getCommand(command); + if (pcmd != null) { + pcmd.setExecutor(this); + pcmd.setTabCompleter(this); + } else { + plugin.getLogger().warning("Failed to register command: /" + command); + } + + return nested; + } + + public MainCommand getMainCommand(String command) { + SimpleNestedCommand nested = command == null ? null : commands.get(command.toLowerCase()); + if (nested != null && nested.parent instanceof MainCommand) { + return (MainCommand) nested.parent; + } + return null; + } + public CommandManager addCommands(AbstractCommand... abstractCommands) { - for (AbstractCommand abstractCommand : abstractCommands) + for (AbstractCommand abstractCommand : abstractCommands) { addCommand(abstractCommand); + } return this; } public CommandManager setExecutor(String command) { - plugin.getCommand(command).setExecutor(this); + PluginCommand pcmd = command == null ? null : plugin.getCommand(command); + if (pcmd != null) { + pcmd.setExecutor(this); + } else { + plugin.getLogger().warning("Failed to register command: /" + command); + } return this; } @@ -116,11 +166,11 @@ public class CommandManager implements CommandExecutor, TabCompleter { public boolean onCommand(CommandSender commandSender, Command command, String label, String[] args) { // grab the specific command that's being called SimpleNestedCommand nested = commands.get(command.getName().toLowerCase()); - if(nested != null) { + if (nested != null) { // check to see if we're trying to call a sub-command - if(args.length != 0 && !nested.children.isEmpty()) { + if (args.length != 0 && !nested.children.isEmpty()) { String subCmd = getSubCommand(nested, args); - if(subCmd != null) { + if (subCmd != null) { // we have a subcommand to use! AbstractCommand sub = nested.children.get(subCmd); // adjust the arguments to match - BREAKING!! @@ -133,26 +183,32 @@ public class CommandManager implements CommandExecutor, TabCompleter { } } // if we've gotten this far, then just use the command we have - if(nested.parent != null) { + if (nested.parent != null) { processRequirements(nested.parent, commandSender, args); return true; } } - commandSender.sendMessage(TextUtils.formatText("&7The command you entered does not exist or is spelt incorrectly.")); + commandSender.sendMessage(msg_noCommand); return true; } private String getSubCommand(SimpleNestedCommand nested, String[] args) { String cmd = args[0].toLowerCase(); - if(nested.children.containsKey(cmd)) + if (nested.children.containsKey(cmd)) { return cmd; - String match = null; - // support for two-argument subcommands - if(args.length >= 2 && nested.children.keySet().stream().anyMatch(k -> k.indexOf(' ') != -1)) { - String cmd2 = String.join(" ", args[0], args[1]); - if(nested.children.containsKey(cmd2)) - return cmd2; } + + String match = null; + // support for mulit-argument subcommands + if (args.length >= 2 && nested.children.keySet().stream().anyMatch(k -> k.indexOf(' ') != -1)) { + for (int len = args.length; len > 1; --len) { + String cmd2 = String.join(" ", Arrays.copyOf(args, len)).toLowerCase(); + if (nested.children.containsKey(cmd2)) { + return cmd2; + } + } + } + // if we don't have a subcommand, should we search for one? if (allowLooseCommands) { // do a "closest match" @@ -173,32 +229,35 @@ public class CommandManager implements CommandExecutor, TabCompleter { private void processRequirements(AbstractCommand command, CommandSender sender, String[] args) { if (!(sender instanceof Player) && command.isNoConsole()) { - sender.sendMessage("&cYou must be a player to use this command..."); + sender.sendMessage(msg_noConsole); return; } if (command.getPermissionNode() == null || sender.hasPermission(command.getPermissionNode())) { AbstractCommand.ReturnType returnType = command.runCommand(sender, args); - if (returnType == AbstractCommand.ReturnType.SYNTAX_ERROR) { - sender.sendMessage(TextUtils.formatText("&cInvalid Syntax!")); - sender.sendMessage(TextUtils.formatText("&7The valid syntax is: &6" + command.getSyntax() + "&7.")); + if (returnType == AbstractCommand.ReturnType.NEEDS_PLAYER) { + sender.sendMessage(msg_noConsole); + } else if (returnType == AbstractCommand.ReturnType.SYNTAX_ERROR) { + for (String s : msg_syntaxError) { + sender.sendMessage(s.replace("%syntax%", command.getSyntax())); + } } return; } - sender.sendMessage(TextUtils.formatText("&cYou do not have permission to do that.")); + sender.sendMessage(msg_noPerms); } @Override public List onTabComplete(CommandSender sender, Command command, String alias, String[] args) { // grab the specific command that's being called SimpleNestedCommand nested = commands.get(command.getName().toLowerCase()); - if(nested != null) { - if(args.length == 0) { + if (nested != null) { + if (args.length == 0) { return nested.parent != null ? nested.parent.onTab(sender, args) : null; } // check for each sub-command that they have access to final boolean op = sender.isOp(); final boolean console = !(sender instanceof Player); - if(args.length == 1) { + if (args.length == 1) { // suggest sub-commands that this user has access to final String arg = args[0].toLowerCase(); return nested.children.entrySet().stream() @@ -211,7 +270,7 @@ public class CommandManager implements CommandExecutor, TabCompleter { // more than one arg, let's check to see if we have a command here String subCmd = getSubCommand(nested, args); AbstractCommand sub; - if(subCmd != null && (sub = nested.children.get(subCmd)) != null + if (subCmd != null && (sub = nested.children.get(subCmd)) != null && (!console || !sub.isNoConsole()) && (op || sub.getPermissionNode() == null || sender.hasPermission(sub.getPermissionNode()))) { // adjust the arguments to match - BREAKING!! @@ -228,11 +287,13 @@ public class CommandManager implements CommandExecutor, TabCompleter { private List fetchList(AbstractCommand abstractCommand, String[] args, CommandSender sender) { List list = abstractCommand.onTab(sender, args); - String str = args[args.length - 1]; - if (list != null && str != null && str.length() >= 1) { - try { - list.removeIf(s -> !s.toLowerCase().startsWith(str.toLowerCase())); - } catch (UnsupportedOperationException ignored) { + if (args.length != 0) { + String str = args[args.length - 1]; + if (list != null && str != null && str.length() >= 1) { + try { + list.removeIf(s -> !s.toLowerCase().startsWith(str.toLowerCase())); + } catch (UnsupportedOperationException ignored) { + } } } return list; @@ -253,7 +314,7 @@ public class CommandManager implements CommandExecutor, TabCompleter { // If we're on Paper 1.8, we need to register timings (spigot creates timings on init, paper creates it on register) // later versions of paper create timings if needed when the command is executed - if(ServerProject.isServer(ServerProject.PAPER, ServerProject.TACO) && ServerVersion.isServerVersionBelow(ServerVersion.V1_9)) { + if (ServerProject.isServer(ServerProject.PAPER, ServerProject.TACO) && ServerVersion.isServerVersionBelow(ServerVersion.V1_9)) { commandObject.timings = co.aikar.timings.TimingsManager.getCommandTiming(plugin.getName().toLowerCase(), commandObject); } diff --git a/Core/src/main/java/com/songoda/core/commands/MainCommand.java b/Core/src/main/java/com/songoda/core/commands/MainCommand.java new file mode 100644 index 00000000..2b8bfc1b --- /dev/null +++ b/Core/src/main/java/com/songoda/core/commands/MainCommand.java @@ -0,0 +1,117 @@ +package com.songoda.core.commands; + +import com.songoda.core.input.ClickableChat; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.plugin.Plugin; + +public class MainCommand extends AbstractCommand { + + String header = null; + String description; + boolean sortHelp = false; + final String command; + final Plugin plugin; + protected final SimpleNestedCommand nestedCommands; + + public MainCommand(Plugin plugin, String command) { + super(CommandType.CONSOLE_OK, command); + this.command = command; + this.plugin = plugin; + this.description = "Shows the command help page for /" + command; + this.nestedCommands = new SimpleNestedCommand(this); + } + + public MainCommand setHeader(String header) { + this.header = header; + return this; + } + + public MainCommand setDescription(String description) { + this.description = description; + return this; + } + + public MainCommand setSortHelp(boolean sortHelp) { + this.sortHelp = sortHelp; + return this; + } + + public MainCommand addSubCommand(AbstractCommand command) { + nestedCommands.addSubCommand(command); + return this; + } + + public MainCommand addSubCommands(AbstractCommand... commands) { + nestedCommands.addSubCommands(commands); + return this; + } + + @Override + protected ReturnType runCommand(CommandSender sender, String... args) { + sender.sendMessage(""); + if (header != null) { + sender.sendMessage(header); + } else { + sender.sendMessage(String.format("%s%s %s» %sVersion %s Created with <3 by %sSongoda", + ChatColor.AQUA.toString() + ChatColor.BOLD, plugin.getDescription().getName(), + ChatColor.DARK_GRAY.toString(), ChatColor.GRAY.toString(), plugin.getDescription().getVersion(), + ChatColor.DARK_PURPLE.toString() + ChatColor.BOLD + ChatColor.ITALIC + )); + } + + if (nestedCommands != null) { + ArrayList commands = new ArrayList(nestedCommands.children.keySet()); + if (sortHelp) { + Collections.sort(commands); + } + boolean isPlayer = sender instanceof Player; + // todo? pagation if commands.size is too large? (player-only) + sender.sendMessage(ChatColor.DARK_GRAY + "- " + ChatColor.GREEN + getSyntax() + ChatColor.GRAY + " - " + getDescription()); + for (String cmdStr : commands) { + final AbstractCommand cmd = nestedCommands.children.get(cmdStr); + if (!isPlayer) { + sender.sendMessage(ChatColor.DARK_GRAY + "- " + ChatColor.GREEN + cmd.getSyntax() + ChatColor.GRAY + " - " + cmd.getDescription()); + } else if (cmd.getPermissionNode() == null || sender.hasPermission(cmd.getPermissionNode())) { + ClickableChat msg = new ClickableChat(); + final String c = "/" + command + " "; + msg.addMessage(ChatColor.DARK_GRAY + "- ") + .addPromptCommand(ChatColor.GREEN + c + cmd.getSyntax(), ChatColor.GREEN + c + cmdStr, c + cmdStr) + .addMessage(ChatColor.GRAY + " - " + cmd.getDescription()); + msg.sendTo((Player) sender); + } + } + } + + sender.sendMessage(""); + + return ReturnType.SUCCESS; + } + + @Override + protected List onTab(CommandSender sender, String... args) { + // don't need to worry about tab for a root command - handled by the manager + return null; + } + + @Override + public String getPermissionNode() { + // permissions for a root command should be handled in the plugin.yml + return null; + } + + @Override + public String getSyntax() { + return "/" + command; + } + + @Override + public String getDescription() { + return description; + } + +} diff --git a/Core/src/main/java/com/songoda/core/commands/SimpleNestedCommand.java b/Core/src/main/java/com/songoda/core/commands/SimpleNestedCommand.java index ff86a1c2..85347c78 100644 --- a/Core/src/main/java/com/songoda/core/commands/SimpleNestedCommand.java +++ b/Core/src/main/java/com/songoda/core/commands/SimpleNestedCommand.java @@ -1,12 +1,12 @@ package com.songoda.core.commands; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.stream.Stream; public class SimpleNestedCommand { final AbstractCommand parent; - final HashMap children = new HashMap(); + final LinkedHashMap children = new LinkedHashMap(); protected SimpleNestedCommand(AbstractCommand parent) { this.parent = parent; From 066b643e120e9a0f19f0b263e446b3629317d2af Mon Sep 17 00:00:00 2001 From: jascotty2 Date: Tue, 8 Oct 2019 14:41:04 -0500 Subject: [PATCH 15/21] sound fixes for 1.9 --- .../core/compatibility/CompatibleSound.java | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Core/src/main/java/com/songoda/core/compatibility/CompatibleSound.java b/Core/src/main/java/com/songoda/core/compatibility/CompatibleSound.java index afa9e590..28b077ff 100644 --- a/Core/src/main/java/com/songoda/core/compatibility/CompatibleSound.java +++ b/Core/src/main/java/com/songoda/core/compatibility/CompatibleSound.java @@ -140,7 +140,7 @@ public enum CompatibleSound { BLOCK_METAL_PRESSURE_PLATE_CLICK_ON(ServerVersion.V1_13, v(ServerVersion.V1_9, "BLOCK_METAL_PRESSUREPLATE_CLICK_ON"), v("WOOD_CLICK", true)), BLOCK_METAL_STEP(ServerVersion.V1_9, v("STEP_STONE", true)), BLOCK_NETHER_WART_BREAK, - BLOCK_NOTE_BLOCK_BANJO(ServerVersion.V1_14, v(ServerVersion.V1_13, "BLOCK_NOTE_BLOCK_GUITAR", true), v(ServerVersion.V1_9, "BLOCK_NOTE_GUITAR", true), v("NOTE_BASS_GUITAR", true)), + BLOCK_NOTE_BLOCK_BANJO(ServerVersion.V1_14, v(ServerVersion.V1_13, "BLOCK_NOTE_BLOCK_GUITAR", true), v(ServerVersion.V1_12, "BLOCK_NOTE_GUITAR", true), v(ServerVersion.V1_9, "BLOCK_NOTE_BASS"), v("NOTE_BASS_GUITAR", true)), BLOCK_NOTE_BLOCK_BASEDRUM(ServerVersion.V1_13, v(ServerVersion.V1_9, "BLOCK_NOTE_BASEDRUM"), v("NOTE_BASS_DRUM")), BLOCK_NOTE_BLOCK_BASS(ServerVersion.V1_13, v(ServerVersion.V1_9, "BLOCK_NOTE_BASS"), v("NOTE_BASS")), BLOCK_NOTE_BLOCK_BELL(ServerVersion.V1_13, v(ServerVersion.V1_12, "BLOCK_NOTE_BELL"), v(ServerVersion.V1_9, "BLOCK_NOTE_HARP", true), v("NOTE_PLING", true)), @@ -152,7 +152,7 @@ public enum CompatibleSound { BLOCK_NOTE_BLOCK_GUITAR(ServerVersion.V1_13, v(ServerVersion.V1_12, "BLOCK_NOTE_GUITAR"), v(ServerVersion.V1_9, "BLOCK_NOTE_HARP", true), v("NOTE_BASS_GUITAR")), // This value disappeared from the API from 1.9-1.11 (returned in 12) BLOCK_NOTE_BLOCK_HARP(ServerVersion.V1_13, v(ServerVersion.V1_9, "BLOCK_NOTE_HARP"), v("NOTE_PIANO")), BLOCK_NOTE_BLOCK_HAT(ServerVersion.V1_13, v(ServerVersion.V1_9, "BLOCK_NOTE_HAT"), v("NOTE_STICKS")), - BLOCK_NOTE_BLOCK_IRON_XYLOPHONE(ServerVersion.V1_14, v(ServerVersion.V1_13, "BLOCK_NOTE_BLOCK_XYLOPHONE", true), v(ServerVersion.V1_9, "BLOCK_NOTE_XYLOPHONE", true), v("NOTE_PLING", true)), + BLOCK_NOTE_BLOCK_IRON_XYLOPHONE(ServerVersion.V1_14, v(ServerVersion.V1_13, "BLOCK_NOTE_BLOCK_XYLOPHONE", true), v(ServerVersion.V1_12, "BLOCK_NOTE_XYLOPHONE"), v(ServerVersion.V1_9, "BLOCK_NOTE_PLING", true), v("NOTE_PLING", true)), BLOCK_NOTE_BLOCK_PLING(ServerVersion.V1_13, v(ServerVersion.V1_9, "BLOCK_NOTE_PLING"), v("NOTE_PLING")), BLOCK_NOTE_BLOCK_SNARE(ServerVersion.V1_13, v(ServerVersion.V1_9, "BLOCK_NOTE_SNARE"), v("NOTE_SNARE_DRUM")), BLOCK_NOTE_BLOCK_XYLOPHONE(ServerVersion.V1_13, v(ServerVersion.V1_12, "BLOCK_NOTE_XYLOPHONE"), v(ServerVersion.V1_9, "BLOCK_NOTE_PLING", true), v("NOTE_PLING", true)), @@ -173,8 +173,8 @@ public enum CompatibleSound { BLOCK_SCAFFOLDING_HIT, BLOCK_SCAFFOLDING_PLACE, BLOCK_SCAFFOLDING_STEP, - BLOCK_SHULKER_BOX_CLOSE("CHEST_CLOSE"), - BLOCK_SHULKER_BOX_OPEN("CHEST_OPEN"), + BLOCK_SHULKER_BOX_CLOSE(v(ServerVersion.V1_9, "BLOCK_ENDERCHEST_CLOSE"), v("CHEST_CLOSE")), + BLOCK_SHULKER_BOX_OPEN(v(ServerVersion.V1_9, "BLOCK_ENDERCHEST_OPEN"), v("CHEST_OPEN")), BLOCK_SLIME_BLOCK_BREAK(ServerVersion.V1_13, v(ServerVersion.V1_9, "BLOCK_SLIME_BREAK"), v(null, true)), BLOCK_SLIME_BLOCK_FALL(ServerVersion.V1_13, v(ServerVersion.V1_9, "BLOCK_SLIME_FALL"), v(null, true)), BLOCK_SLIME_BLOCK_HIT(ServerVersion.V1_13, v(ServerVersion.V1_9, "BLOCK_SLIME_HIT"), v(null, true)), @@ -430,11 +430,11 @@ public enum CompatibleSound { ENTITY_LIGHTNING_BOLT_THUNDER(ServerVersion.V1_13, v(ServerVersion.V1_9, "ENTITY_LIGHTNING_THUNDER"), v("AMBIENCE_THUNDER")), ENTITY_LINGERING_POTION_THROW, ENTITY_LLAMA_AMBIENT, - ENTITY_LLAMA_ANGRY, + ENTITY_LLAMA_ANGRY(v(ServerVersion.V1_11, "ENTITY_HORSE_ANGRY"), v("HORSE_ANGRY")), ENTITY_LLAMA_CHEST, - ENTITY_LLAMA_DEATH, - ENTITY_LLAMA_EAT("EAT"), - ENTITY_LLAMA_HURT, + ENTITY_LLAMA_DEATH(v(ServerVersion.V1_11, "ENTITY_HORSE_DEATH"), v("HORSE_DEATH")), + ENTITY_LLAMA_EAT(v(ServerVersion.V1_11, "ENTITY_HORSE_EAT"), v("EAT")), + ENTITY_LLAMA_HURT(v(ServerVersion.V1_11, "ENTITY_HORSE_HURT"), v("HORSE_HIT")), ENTITY_LLAMA_SPIT, ENTITY_LLAMA_STEP, ENTITY_LLAMA_SWAG, From 716a8e594f1633f5c260036ca10075a2334b1507 Mon Sep 17 00:00:00 2001 From: jascotty2 Date: Tue, 8 Oct 2019 15:51:21 -0500 Subject: [PATCH 16/21] Add selector parse API --- .../core/commands/SelectorArguments.java | 192 ++++++++++++++++++ .../core/compatibility/EntityNamespace.java | 85 ++++++++ 2 files changed, 277 insertions(+) create mode 100644 Core/src/main/java/com/songoda/core/commands/SelectorArguments.java create mode 100644 Core/src/main/java/com/songoda/core/compatibility/EntityNamespace.java diff --git a/Core/src/main/java/com/songoda/core/commands/SelectorArguments.java b/Core/src/main/java/com/songoda/core/commands/SelectorArguments.java new file mode 100644 index 00000000..805e407e --- /dev/null +++ b/Core/src/main/java/com/songoda/core/commands/SelectorArguments.java @@ -0,0 +1,192 @@ +package com.songoda.core.commands; + +import com.songoda.core.compatibility.EntityNamespace; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import org.bukkit.Location; +import org.bukkit.command.BlockCommandSender; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Entity; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public class SelectorArguments { + + static Pattern selectorPattern = Pattern.compile("^(@[apers])(\\[(.*?)\\])?$"); + static Pattern selectorRangePattern = Pattern.compile("^([0-9]{1,9}(\\.[0-9]{1,9})?)?(\\.\\.)?([0-9]{1,9}(\\.[0-9]{1,9})?)?$"); + + /** + * Parse a command selector using Minecraft's selector format.
+ * Currently only supports distance and entity type + * + * @param sender CommandBlock or Player running the command + * @param argument argument with the selector to parse + * @return SelectorArguments Object for grabbing the list of entities, or null if the selector is invalid + */ + @Nullable + public static SelectorArguments parseSelector(@NotNull CommandSender sender, @NotNull String argument) { + if (!(sender instanceof BlockCommandSender || sender instanceof Player)) { + return null; + } + Matcher m = selectorPattern.matcher(argument); + if (!m.find()) { + return null; + } + SelectorType type = SelectorType.getType(m.group(1)); + if (type == null) { + return null; + } + SelectorArguments selector = new SelectorArguments(sender, type); + + if (m.group(3) != null) { + selector.parseArguments(m.group(3)); + } + + return selector; + } + + protected final CommandSender sender; + protected final SelectorType selector; + protected double rangeMin = 0, rangeMax = Double.POSITIVE_INFINITY; + protected EntityType entityType; + + public SelectorArguments(CommandSender sender, SelectorType type) { + this.sender = sender; + this.selector = type; + } + + private void parseArguments(String selectorArgs) { + String[] args = selectorArgs.split(","); + for (String s : args) { + if (s.contains("=")) { + String[] v = s.split("="); + if (v[0].equals("distance")) { + // 10 = d == 10 + // 10..12 = d > 10 && d <= 12 + // 5.. = d >= 5 + // ..5 = d <= 15 + Matcher distGroup = selectorRangePattern.matcher(v[1]); + if (distGroup.find()) { + if (distGroup.group(1) != null) { + rangeMin = Double.parseDouble(distGroup.group(1)); + } + if (distGroup.group(3) == null) { + rangeMax = rangeMin; + } else if (distGroup.group(4) != null) { + rangeMax = Double.parseDouble(distGroup.group(4)); + } + } + } else if (v[0].equals("type")) { + entityType = EntityNamespace.minecraftToBukkit(v[1]); + } + // more arguments can be parsed here (TODO) + } + } + /* + advancements Advancement earned by entity. + distance Distance to entity. + dx Entities between x and x + dx. + dy Entities between y and y + dy. + dz Entities between z and z + dz. + gamemode Players with gamemode. It can be one of the following values: adventure, creative, spectator, survival, !adventure, !creative, !spectator, !survival + level Experience level. It must be an integer value that is 0 or greater. + limit Maximum number of entities to target. It must be an integer value that is 1 or greater. + name Entity name. + nbt NBT tag. + scores Score. + sort Sort the entities. It must be one of the following values: arbitrary, furthest, nearest, random + tag Scoreboard tag. + team Entities on team. + type Entity type (target must be the specified entity type - https://www.digminecraft.com/lists/entity_list_pc.php ). + x Entity's x-coordinate position. + x_rotation Entity's x rotation (vertical rotation). + y Entity's y-coordinate position. + y_rotation Entity's y rotation (horizontal rotation). + z Entity's z-coordinate position. + target selector arguments are case-sensitive + @e[type=cow,limit=5] + */ + } + + public Collection getSelection() { + final Location location = sender instanceof Player ? ((Player) sender).getLocation() : ((BlockCommandSender) sender).getBlock().getLocation(); + Collection list = preSelect(location); + if (list.isEmpty()) { + return list; + } + List list2 = filter(location, list); + if (list2.isEmpty()) { + return list2; + } + switch (selector) { + case PLAYER: + Collections.sort(list2, (o1, o2) -> (int) (o1.getLocation().distanceSquared(location) - o2.getLocation().distanceSquared(location))); + return Arrays.asList(list2.get(0)); + case RANDOM_PLAYER: + Collections.shuffle(list2); + return Arrays.asList(list2.get(0)); + case ALL_PLAYER: + case ALL_ENTITIES: + case SELF: + return list2; + } + return list2; + } + + protected Collection preSelect(Location location) { + switch (selector) { + case PLAYER: + case RANDOM_PLAYER: + case ALL_PLAYER: + return rangeMax == Double.POSITIVE_INFINITY + ? location.getWorld().getEntitiesByClasses(Player.class) + : location.getWorld().getNearbyEntities(location, rangeMax * 2, rangeMax * 2, rangeMax * 2).stream() + .filter(e -> e instanceof Player).collect(Collectors.toSet()); + case ALL_ENTITIES: + return rangeMax == Double.POSITIVE_INFINITY + ? location.getWorld().getEntities() + : location.getWorld().getNearbyEntities(location, rangeMax * 2, rangeMax * 2, rangeMax * 2); + case SELF: + return sender instanceof Entity ? Arrays.asList((Entity) sender) : Collections.EMPTY_LIST; + } + return Collections.EMPTY_LIST; + } + + protected List filter(Location location, Collection list) { + Stream stream = list.stream() + .filter(p -> rangeMin == 0 || p.getLocation().distance(location) > rangeMin) + .filter(e -> entityType == null || e.getType() == entityType); + return stream.collect(Collectors.toList()); + } + + public static enum SelectorType { + + PLAYER, RANDOM_PLAYER, ALL_PLAYER, ALL_ENTITIES, SELF; + + public static SelectorType getType(String str) { + if (str != null) { + switch (str.toLowerCase()) { + case "@p": + return PLAYER; + case "@r": + return RANDOM_PLAYER; + case "@a": + return ALL_PLAYER; + case "@e": + return ALL_ENTITIES; + case "@s": + return SELF; + } + } + return null; + } + } +} diff --git a/Core/src/main/java/com/songoda/core/compatibility/EntityNamespace.java b/Core/src/main/java/com/songoda/core/compatibility/EntityNamespace.java new file mode 100644 index 00000000..386e30ca --- /dev/null +++ b/Core/src/main/java/com/songoda/core/compatibility/EntityNamespace.java @@ -0,0 +1,85 @@ +package com.songoda.core.compatibility; + +import java.util.HashMap; +import java.util.Map; +import org.bukkit.entity.EntityType; + +public class EntityNamespace { + + static final HashMap validTypes = new HashMap(); + static final HashMap legacyToModernTypes = new HashMap() { + { + put("xporb", "experience_orb"); + put("xp_orb", "experience_orb"); + put("leashknot", "leash_knot"); + put("smallfireball", "small_fireball"); + put("thrownenderpearl", "ender_pearl"); + put("eyeofendersignal", "eye_of_ender"); + put("eye_of_ender_signal", "eye_of_ender"); + put("thrownexpbottle", "experience_bottle"); + put("xp_bottle", "experience_bottle"); + put("itemframe", "item_frame"); + put("witherskull", "wither_skull"); + put("primedtnt", "tnt"); + put("fallingsand", "falling_block"); + put("fireworksrocketentity", "firework_rocket"); + put("fireworks_rocket", "firework_rocket"); + put("spectralarrow", "spectral_arrow"); + put("tippedarrow", "arrow"); + put("shulkerbullet", "shulker_bullet"); + put("dragonfireball", "dragon_fireball"); + put("armorstand", "armor_stand"); + put("minecartcommandblock", "command_block_minecart"); + put("commandblock_minecart", "command_block_minecart"); + put("minecartrideable", "minecart"); + put("minecartchest", "chest_minecart"); + put("minecartfurnace", "furnace_minecart"); + put("minecarttnt", "tnt_minecart"); + put("minecarthopper", "hopper_minecart"); + put("minecartmobspawner", "spawner_minecart"); + put("pigzombie", "zombie_pigman"); + put("cavespider", "cave_spider"); + put("lavaslime", "magma_cube"); + put("enderdragon", "ender_dragon"); + put("witherboss", "wither"); + put("mushroomcow", "mooshroom"); + put("snowman", "snow_golem"); + put("snowman", "snow_golem"); + put("ozelot", "ocelot"); + put("villagergolem", "iron_golem"); + put("villager_golem", "iron_golem"); + put("entityhorse", "horse"); + put("endercrystal", "end_crystal"); + put("ender_crystal", "end_crystal"); + } + }; + + static { + for (EntityType t : EntityType.values()) { + if (t.getName() != null) { + validTypes.put(t.getName().toLowerCase(), t); + } + } + } + + public static EntityType minecraftToBukkit(String entity) { + if (entity == null) { + return null; + } + // first try to translate natively + EntityType type = EntityType.fromName(entity); + if (type == null) { + // try legacy values + type = EntityType.fromName(legacyToModernTypes.get(entity)); + // try converting modern to legacy + if (type == null && legacyToModernTypes.containsValue(entity)) { + for (Map.Entry e : legacyToModernTypes.entrySet()) { + if (e.getValue().equals(entity) && (type = EntityType.fromName(legacyToModernTypes.get(e.getKey()))) != null) { + return type; + } + } + } + } + return type; + } +} From 15a191a8b003bee821e09065d762508fde72583f Mon Sep 17 00:00:00 2001 From: jascotty2 Date: Wed, 9 Oct 2019 16:53:38 -0500 Subject: [PATCH 17/21] add jobs hooks --- Core/pom.xml | 68 ++--- .../java/com/songoda/core/hooks/JobsHook.java | 232 ++++++++++++++++++ .../com/songoda/core/hooks/McMMOHook.java | 17 ++ .../songoda/core/hooks/jobs/JobsHandler.java | 12 + .../core/hooks/jobs/JobsPlayerHandler.java | 182 ++++++++++++++ .../worldguard/WorldGuardFlagHandler.java | 1 - 6 files changed, 481 insertions(+), 31 deletions(-) create mode 100644 Core/src/main/java/com/songoda/core/hooks/JobsHook.java create mode 100644 Core/src/main/java/com/songoda/core/hooks/McMMOHook.java create mode 100644 Core/src/main/java/com/songoda/core/hooks/jobs/JobsHandler.java create mode 100644 Core/src/main/java/com/songoda/core/hooks/jobs/JobsPlayerHandler.java diff --git a/Core/pom.xml b/Core/pom.xml index 5a914de6..6d5cda8a 100644 --- a/Core/pom.xml +++ b/Core/pom.xml @@ -183,6 +183,7 @@ compile + com.gmail.filoghost.holographicdisplays holographicdisplays-api @@ -231,6 +232,43 @@ 4.29 provided + + com.sk89q.worldguard + worldguard-bukkit + 7.0.0 + provided + + + com.sk89q.worldedit + worldedit-bukkit + 7.0.0 + provided + + + com.songoda + UltimateStacker + 1.9.6 + provided + + + com.bgsoftware + WildStacker + 2-9-0 + provided + + + uk.antiperson + stackmob + 4-0-2 + provided + + + com.gamingmesh + jobs + 4.13.0 + provided + + com.googlecode.json-simple json-simple @@ -266,35 +304,5 @@ sqlite-jdbc 3.23.1 - - com.sk89q.worldguard - worldguard-bukkit - 7.0.0 - provided - - - com.sk89q.worldedit - worldedit-bukkit - 7.0.0 - provided - - - com.songoda - UltimateStacker - 1.9.6 - provided - - - com.bgsoftware - WildStacker - 2-9-0 - provided - - - uk.antiperson - stackmob - 4-0-2 - provided - diff --git a/Core/src/main/java/com/songoda/core/hooks/JobsHook.java b/Core/src/main/java/com/songoda/core/hooks/JobsHook.java new file mode 100644 index 00000000..4a30c1fc --- /dev/null +++ b/Core/src/main/java/com/songoda/core/hooks/JobsHook.java @@ -0,0 +1,232 @@ +package com.songoda.core.hooks; + +import com.songoda.core.hooks.jobs.JobsHandler; +import com.songoda.core.hooks.jobs.JobsPlayerHandler; +import java.util.Collections; +import java.util.List; +import org.bukkit.block.Block; +import org.bukkit.entity.Entity; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; + +public class JobsHook { + + static boolean canHook; + + static { + try { + // if this class exists, we're good to use Jobs classes + Class.forName("com.gamingmesh.jobs.Jobs"); + canHook = true; + } catch (ClassNotFoundException ex) { + } + } + + public static JobsPlayerHandler getPlayer(Player player) { + if (canHook) { + return JobsPlayerHandler.loadPlayer(player); + } + return null; + } + + public static boolean isEnabled() { + return canHook; + } + + public static List getAllJobs() { + if (canHook) { + return JobsHandler.getJobs(); + } + return Collections.EMPTY_LIST; + } + + public static double getBoostExp(Player player, String job) { + JobsPlayerHandler jPlayer = getPlayer(player); + if (jPlayer != null) { + return jPlayer.getBoostExp(job); + } + return -1; + } + + public static double getBoostMoney(Player player, String job) { + JobsPlayerHandler jPlayer = getPlayer(player); + if (jPlayer != null) { + return jPlayer.getBoostMoney(job); + } + return -1; + } + + public static double getBoostPoints(Player player, String job) { + JobsPlayerHandler jPlayer = getPlayer(player); + if (jPlayer != null) { + return jPlayer.getBoostPoints(job); + } + return -1; + } + + public static void promoteJob(Player player, String job) { + JobsPlayerHandler jPlayer = getPlayer(player); + if (jPlayer != null) { + jPlayer.promoteJob(job); + } + } + + public static void promoteJob(Player player, String job, int levels) { + JobsPlayerHandler jPlayer = getPlayer(player); + if (jPlayer != null) { + jPlayer.promoteJob(job, levels); + } + } + + public static void demoteJob(Player player, String job) { + JobsPlayerHandler jPlayer = getPlayer(player); + if (jPlayer != null) { + jPlayer.demoteJob(job); + } + } + + public static void demoteJob(Player player, String job, int levels) { + JobsPlayerHandler jPlayer = getPlayer(player); + if (jPlayer != null) { + jPlayer.demoteJob(job, levels); + } + } + + public static void joinJob(Player player, String job) { + JobsPlayerHandler jPlayer = getPlayer(player); + if (jPlayer != null) { + jPlayer.joinJob(job); + } + } + + public static void leaveAllJobs(Player player) { + JobsPlayerHandler jPlayer = getPlayer(player); + if (jPlayer != null) { + jPlayer.leaveAllJobs(); + } + } + + public static void leaveJob(Player player, String job) { + JobsPlayerHandler jPlayer = getPlayer(player); + if (jPlayer != null) { + jPlayer.leaveJob(job); + } + } + + public static int getTotalLevels(Player player) { + JobsPlayerHandler jPlayer = getPlayer(player); + if (jPlayer != null) { + return jPlayer.getTotalLevels(); + } + return -1; + } + + public static int getMaxBrewingStandsAllowed(Player player) { + JobsPlayerHandler jPlayer = getPlayer(player); + if (jPlayer != null) { + return jPlayer.getMaxBrewingStandsAllowed(); + } + return -1; + } + + public static int getMaxFurnacesAllowed(Player player) { + JobsPlayerHandler jPlayer = getPlayer(player); + if (jPlayer != null) { + return jPlayer.getMaxFurnacesAllowed(); + } + return -1; + } + + public static List getJobs(Player player) { + JobsPlayerHandler jPlayer = getPlayer(player); + if (jPlayer != null) { + return jPlayer.getJobs(); + } + return Collections.EMPTY_LIST; + } + + public static void eatItem(Player player, ItemStack item) { + JobsPlayerHandler jPlayer = getPlayer(player); + if (jPlayer != null) { + jPlayer.eatItem(item); + } + } + + public static void breakBlock(Player player, Block block) { + JobsPlayerHandler jPlayer = getPlayer(player); + if (jPlayer != null) { + jPlayer.breakBlock(block); + } + } + + public static void tntBreakBlock(Player player, Block block) { + JobsPlayerHandler jPlayer = getPlayer(player); + if (jPlayer != null) { + jPlayer.tntBreakBlock(block); + } + } + + public static void placeBlock(Player player, Block block) { + JobsPlayerHandler jPlayer = getPlayer(player); + if (jPlayer != null) { + jPlayer.placeBlock(block); + } + } + + public static void placeEntity(Player player, Entity block) { + JobsPlayerHandler jPlayer = getPlayer(player); + if (jPlayer != null) { + jPlayer.placeEntity(block); + } + } + + public static void breakEntity(Player player, Entity block) { + JobsPlayerHandler jPlayer = getPlayer(player); + if (jPlayer != null) { + jPlayer.breakEntity(block); + } + } + + public static void breedEntity(Player player, LivingEntity entity) { + JobsPlayerHandler jPlayer = getPlayer(player); + if (jPlayer != null) { + jPlayer.breedEntity(entity); + } + } + + public static void killEntity(Player player, LivingEntity entity) { + JobsPlayerHandler jPlayer = getPlayer(player); + if (jPlayer != null) { + jPlayer.killEntity(entity); + } + } + + public static void tameEntity(Player player, LivingEntity entity) { + JobsPlayerHandler jPlayer = getPlayer(player); + if (jPlayer != null) { + jPlayer.tameEntity(entity); + } + } + + public static void catchFish(Player player, ItemStack items) { + JobsPlayerHandler jPlayer = getPlayer(player); + if (jPlayer != null) { + jPlayer.catchFish(items); + } + } + + public static void killEntity(Player player, LivingEntity entity, Entity damageSource) { + JobsPlayerHandler jPlayer = getPlayer(player); + if (jPlayer != null) { + jPlayer.killEntity(entity, damageSource); + } + } + + public static void itemEnchanted(Player player, ItemStack resultStack) { + JobsPlayerHandler jPlayer = getPlayer(player); + if (jPlayer != null) { + jPlayer.itemEnchanted(resultStack); + } + } +} diff --git a/Core/src/main/java/com/songoda/core/hooks/McMMOHook.java b/Core/src/main/java/com/songoda/core/hooks/McMMOHook.java new file mode 100644 index 00000000..0d5e53c6 --- /dev/null +++ b/Core/src/main/java/com/songoda/core/hooks/McMMOHook.java @@ -0,0 +1,17 @@ +package com.songoda.core.hooks; + +public class McMMOHook { + + static boolean canHook = false; + + static { + try { + // if this class exists, we're good to use WG classes + Class.forName("com.sk89q.worldguard.protection.flags.Flag"); + canHook = true; + } catch (ClassNotFoundException ex) { + } + } + + +} diff --git a/Core/src/main/java/com/songoda/core/hooks/jobs/JobsHandler.java b/Core/src/main/java/com/songoda/core/hooks/jobs/JobsHandler.java new file mode 100644 index 00000000..87e85148 --- /dev/null +++ b/Core/src/main/java/com/songoda/core/hooks/jobs/JobsHandler.java @@ -0,0 +1,12 @@ +package com.songoda.core.hooks.jobs; + +import com.gamingmesh.jobs.Jobs; +import java.util.List; +import java.util.stream.Collectors; + +public class JobsHandler { + + public static List getJobs() { + return Jobs.getJobs().stream().map(j -> j.getName()).collect(Collectors.toList()); + } +} diff --git a/Core/src/main/java/com/songoda/core/hooks/jobs/JobsPlayerHandler.java b/Core/src/main/java/com/songoda/core/hooks/jobs/JobsPlayerHandler.java new file mode 100644 index 00000000..a4e477d9 --- /dev/null +++ b/Core/src/main/java/com/songoda/core/hooks/jobs/JobsPlayerHandler.java @@ -0,0 +1,182 @@ +package com.songoda.core.hooks.jobs; + +import com.gamingmesh.jobs.CMILib.CMIEnchantment; +import com.gamingmesh.jobs.Jobs; +import com.gamingmesh.jobs.actions.BlockActionInfo; +import com.gamingmesh.jobs.actions.CustomKillInfo; +import com.gamingmesh.jobs.actions.EnchantActionInfo; +import com.gamingmesh.jobs.actions.EntityActionInfo; +import com.gamingmesh.jobs.actions.ItemActionInfo; +import com.gamingmesh.jobs.container.ActionType; +import com.gamingmesh.jobs.container.CurrencyType; +import com.gamingmesh.jobs.container.Job; +import com.gamingmesh.jobs.container.JobProgression; +import com.gamingmesh.jobs.container.JobsPlayer; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import org.bukkit.block.Block; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.entity.Entity; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; + +public class JobsPlayerHandler { + + protected final JobsPlayer jPlayer; + + protected JobsPlayerHandler(JobsPlayer jPlayer) { + this.jPlayer = jPlayer; + } + + public static JobsPlayerHandler loadPlayer(Player player) { + JobsPlayer jPlayer = Jobs.getPlayerManager().getJobsPlayer(player); + return jPlayer != null ? new JobsPlayerHandler(jPlayer) : null; + } + + public double getBoostExp(String job) { + return jPlayer.getBoost(job, CurrencyType.EXP); + } + + public double getBoostMoney(String job) { + return jPlayer.getBoost(job, CurrencyType.MONEY); + } + + public double getBoostPoints(String job) { + return jPlayer.getBoost(job, CurrencyType.POINTS); + } + + public void promoteJob(String jobName) { + Job job = Jobs.getJob(jobName); + if (job != null) { + jPlayer.promoteJob(job, 1); + } + } + + public void promoteJob(String jobName, int levels) { + Job job = Jobs.getJob(jobName); + if (job != null) { + jPlayer.promoteJob(job, levels); + } + } + + public void demoteJob(String jobName) { + Job job = Jobs.getJob(jobName); + if (job != null) { + jPlayer.demoteJob(job, 1); + } + } + + public void demoteJob(String jobName, int levels) { + Job job = Jobs.getJob(jobName); + if (job != null) { + jPlayer.demoteJob(job, levels); + } + } + + public void joinJob(String jobName) { + Job job = Jobs.getJob(jobName); + if (job != null) { + jPlayer.joinJob(job); + } + } + + public void leaveAllJobs() { + jPlayer.leaveAllJobs(); + } + + public void leaveJob(String jobName) { + Job job = Jobs.getJob(jobName); + if (job != null) { + jPlayer.leaveJob(job); + } + } + + public int getTotalLevels() { + return jPlayer.getTotalLevels(); + } + + public int getMaxBrewingStandsAllowed() { + return jPlayer.getMaxBrewingStandsAllowed(); + } + + public int getMaxFurnacesAllowed() { + return jPlayer.getMaxFurnacesAllowed(); + } + + public List getJobs() { + return jPlayer.getJobProgression().stream().map(p -> p.getJob().getName()).collect(Collectors.toList()); + } + + public void eatItem(ItemStack item) { + Jobs.action(jPlayer, new ItemActionInfo(item, ActionType.EAT)); + } + + public void breakBlock(Block block) { + Jobs.action(jPlayer, new BlockActionInfo(block, ActionType.BREAK), block); + } + + public void tntBreakBlock(Block block) { + Jobs.action(jPlayer, new BlockActionInfo(block, ActionType.TNTBREAK), block); + } + + public void placeBlock(Block block) { + Jobs.action(jPlayer, new BlockActionInfo(block, ActionType.PLACE), block); + } + + public void placeEntity(Entity block) { + Jobs.action(jPlayer, new EntityActionInfo(block, ActionType.PLACE)); + } + + public void breakEntity(Entity block) { + Jobs.action(jPlayer, new EntityActionInfo(block, ActionType.BREAK)); + } + + public void breedEntity(LivingEntity entity) { + Jobs.action(jPlayer, new EntityActionInfo(entity, ActionType.BREED)); + } + + public void killEntity(LivingEntity entity) { + killEntity(entity, jPlayer.getPlayer()); + } + + public void tameEntity(LivingEntity entity) { + Jobs.action(jPlayer, new EntityActionInfo((Entity) entity, ActionType.TAME)); + } + + public void catchFish(ItemStack items) { + Jobs.action(jPlayer, new ItemActionInfo(items, ActionType.FISH)); + } + + public void killEntity(LivingEntity entity, Entity damageSource) { + Jobs.action(jPlayer, new EntityActionInfo(entity, ActionType.KILL), damageSource, entity); + if (entity instanceof Player && !entity.hasMetadata("NPC")) { + JobsPlayer jVictim = Jobs.getPlayerManager().getJobsPlayer((Player) entity); + if (jVictim == null) { + return; + } + List jobs = jVictim.getJobProgression(); + if (jobs == null) { + return; + } + for (JobProgression job : jobs) { + Jobs.action(jPlayer, new CustomKillInfo(job.getJob().getName(), ActionType.CUSTOMKILL), damageSource, entity); + } + } + } + + public void itemEnchanted(ItemStack resultStack) { + Map enchants = resultStack.getEnchantments(); + for (Map.Entry oneEnchant : enchants.entrySet()) { + CMIEnchantment e; + String enchantName; + Integer level2; + Enchantment enchant = oneEnchant.getKey(); + if (enchant == null || (enchantName = (e = CMIEnchantment.get(enchant)) == null ? null : e.toString()) == null || (level2 = oneEnchant.getValue()) == null) { + continue; + } + Jobs.action(jPlayer, new EnchantActionInfo(enchantName, level2, ActionType.ENCHANT)); + } + } +} diff --git a/Core/src/main/java/com/songoda/core/hooks/worldguard/WorldGuardFlagHandler.java b/Core/src/main/java/com/songoda/core/hooks/worldguard/WorldGuardFlagHandler.java index 849956a0..4923405b 100644 --- a/Core/src/main/java/com/songoda/core/hooks/worldguard/WorldGuardFlagHandler.java +++ b/Core/src/main/java/com/songoda/core/hooks/worldguard/WorldGuardFlagHandler.java @@ -10,7 +10,6 @@ import com.sk89q.worldguard.protection.flags.StateFlag; import com.sk89q.worldguard.protection.flags.StateFlag.State; import com.sk89q.worldguard.protection.managers.RegionManager; import com.sk89q.worldguard.protection.regions.ProtectedCuboidRegion; -import com.sk89q.worldguard.protection.regions.RegionContainer; import com.sk89q.worldguard.protection.regions.RegionQuery; import java.lang.reflect.Constructor; import java.lang.reflect.Field; From aeafb31b0454e6145f7edc4e503e4c41929f8e86 Mon Sep 17 00:00:00 2001 From: jascotty2 Date: Wed, 9 Oct 2019 19:31:33 -0500 Subject: [PATCH 18/21] add McMMO hooks --- Core/pom.xml | 6 + .../com/songoda/core/hooks/McMMOHook.java | 223 +++++++- .../core/hooks/mcmmo/McMMOHandler.java | 514 ++++++++++++++++++ 3 files changed, 738 insertions(+), 5 deletions(-) create mode 100644 Core/src/main/java/com/songoda/core/hooks/mcmmo/McMMOHandler.java diff --git a/Core/pom.xml b/Core/pom.xml index 6d5cda8a..04b9827b 100644 --- a/Core/pom.xml +++ b/Core/pom.xml @@ -268,6 +268,12 @@ 4.13.0 provided + + com.gmail.nossr50 + mcmmo + 2.1.50 + provided + com.googlecode.json-simple diff --git a/Core/src/main/java/com/songoda/core/hooks/McMMOHook.java b/Core/src/main/java/com/songoda/core/hooks/McMMOHook.java index 0d5e53c6..903bdc4e 100644 --- a/Core/src/main/java/com/songoda/core/hooks/McMMOHook.java +++ b/Core/src/main/java/com/songoda/core/hooks/McMMOHook.java @@ -1,17 +1,230 @@ package com.songoda.core.hooks; +import com.songoda.core.hooks.mcmmo.McMMOHandler; +import java.util.Collection; +import org.bukkit.block.Block; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; + public class McMMOHook { static boolean canHook = false; static { - try { - // if this class exists, we're good to use WG classes - Class.forName("com.sk89q.worldguard.protection.flags.Flag"); + try { + // if this class exists, we're good to use McMMO + Class.forName("com.gmail.nossr50.api.AbilityAPI"); canHook = true; } catch (ClassNotFoundException ex) { } } - - + + public static void addMining(Player player, Collection blocks) { + if (canHook) { + McMMOHandler.addMining(player, blocks); + } + } + + public static void addExcavation(Player player, Collection blocks) { + if (canHook) { + McMMOHandler.addExcavation(player, blocks); + } + } + + public static void addHerbalism(Player player, Collection blocks) { + if (canHook) { + McMMOHandler.addHerbalism(player, blocks); + } + } + + public static void addWoodcutting(Player player, Collection blocks) { + if (canHook) { + McMMOHandler.addWoodcutting(player, blocks); + } + } + + public static int getAcrobaticsSkill(Player player) { + return canHook ? McMMOHandler.getAcrobaticsSkill(player) : -1; + } + + public static int getAlchemySkill(Player player) { + return canHook ? McMMOHandler.getAlchemySkill(player) : -1; + } + + public static int getArcherySkill(Player player) { + return canHook ? McMMOHandler.getArcherySkill(player) : -1; + } + + public static int getAxesSkill(Player player) { + return canHook ? McMMOHandler.getAxesSkill(player) : -1; + } + + public static int getExcavationSkill(Player player) { + return canHook ? McMMOHandler.getExcavationSkill(player) : -1; + } + + public static int getFishingSkill(Player player) { + return canHook ? McMMOHandler.getFishingSkill(player) : -1; + } + + public static int getHerbalismSkill(Player player) { + return canHook ? McMMOHandler.getHerbalismSkill(player) : -1; + } + + public static int getMiningSkill(Player player) { + return canHook ? McMMOHandler.getMiningSkill(player) : -1; + } + + public static int getRepairSkill(Player player) { + return canHook ? McMMOHandler.getRepairSkill(player) : -1; + } + + public static int getSmeltingSkill(Player player) { + return canHook ? McMMOHandler.getSmeltingSkill(player) : -1; + } + + public static int getSwordsSkill(Player player) { + return canHook ? McMMOHandler.getSwordsSkill(player) : -1; + } + + public static int getTamingSkill(Player player) { + return canHook ? McMMOHandler.getTamingSkill(player) : -1; + } + + public static int getUnarmedSkill(Player player) { + return canHook ? McMMOHandler.getUnarmedSkill(player) : -1; + } + + public static int getWoodcuttingSkill(Player player) { + return canHook ? McMMOHandler.getWoodcuttingSkill(player) : -1; + } + + public static void addAcrobatics(Player player, int xp) { + if (canHook) { + McMMOHandler.addAcrobatics(player, xp); + } + } + + public static void addAlchemy(Player player, int xp) { + if (canHook) { + McMMOHandler.addAlchemy(player, xp); + } + } + + public static void addArchery(Player player, int xp) { + if (canHook) { + McMMOHandler.addArchery(player, xp); + } + } + + public static void addAxes(Player player, int xp) { + if (canHook) { + McMMOHandler.addAxes(player, xp); + } + } + + public static void addExcavation(Player player, int xp) { + if (canHook) { + McMMOHandler.addExcavation(player, xp); + } + } + + public static void addFishing(Player player, int xp) { + if (canHook) { + McMMOHandler.addFishing(player, xp); + } + } + + public static void addHerbalism(Player player, int xp) { + if (canHook) { + McMMOHandler.addHerbalism(player, xp); + } + } + + public static void addMining(Player player, int xp) { + if (canHook) { + McMMOHandler.addMining(player, xp); + } + } + + public static void addRepair(Player player, int xp) { + if (canHook) { + McMMOHandler.addRepair(player, xp); + } + } + + public static void addSmelting(Player player, int xp) { + if (canHook) { + McMMOHandler.addSmelting(player, xp); + } + } + + public static void addSwords(Player player, int xp) { + if (canHook) { + McMMOHandler.addSwords(player, xp); + } + } + + public static void addTaming(Player player, int xp) { + if (canHook) { + McMMOHandler.addTaming(player, xp); + } + } + + public static void addUnarmed(Player player, int xp) { + if (canHook) { + McMMOHandler.addUnarmed(player, xp); + } + } + + public static void addWoodcutting(Player player, int xp) { + if (canHook) { + McMMOHandler.addWoodcutting(player, xp); + } + } + + public static boolean hasHerbalismDoubleDrops(Player player) { + return canHook ? McMMOHandler.hasHerbalismDoubleDrops(player) : false; + } + + public static boolean hasMiningDoubleDrops(Player player) { + return canHook ? McMMOHandler.hasMiningDoubleDrops(player) : false; + } + + public static boolean hasWoodcuttingDoubleDrops(Player player) { + return canHook ? McMMOHandler.hasWoodcuttingDoubleDrops(player) : false; + } + + public static boolean isUsingBerserk(Player player) { + return canHook ? McMMOHandler.isUsingBerserk(player) : false; + } + + public static boolean isUsingGigaDrill(Player player) { + return canHook ? McMMOHandler.isUsingGigaDrill(player) : false; + } + + public static boolean isUsingGreenTerra(Player player) { + return canHook ? McMMOHandler.isUsingGreenTerra(player) : false; + } + + public static boolean isUsingSerratedStrikes(Player player) { + return canHook ? McMMOHandler.isUsingSerratedStrikes(player) : false; + } + + public static boolean isUsingSkullSplitter(Player player) { + return canHook ? McMMOHandler.isUsingSkullSplitter(player) : false; + } + + public static boolean isUsingSuperBreaker(Player player) { + return canHook ? McMMOHandler.isUsingSuperBreaker(player) : false; + } + + public static boolean isUsingTreeFeller(Player player) { + return canHook ? McMMOHandler.isUsingTreeFeller(player) : false; + } + + public static boolean isBleeding(LivingEntity victim) { + return canHook ? McMMOHandler.isBleeding(victim) : false; + } + } diff --git a/Core/src/main/java/com/songoda/core/hooks/mcmmo/McMMOHandler.java b/Core/src/main/java/com/songoda/core/hooks/mcmmo/McMMOHandler.java new file mode 100644 index 00000000..2b8a3d5e --- /dev/null +++ b/Core/src/main/java/com/songoda/core/hooks/mcmmo/McMMOHandler.java @@ -0,0 +1,514 @@ +package com.songoda.core.hooks.mcmmo; + +import com.gmail.nossr50.api.AbilityAPI; +import com.gmail.nossr50.api.ExperienceAPI; +import com.gmail.nossr50.config.experience.ExperienceConfig; +import com.gmail.nossr50.datatypes.experience.XPGainReason; +import com.gmail.nossr50.datatypes.experience.XPGainSource; +import com.gmail.nossr50.datatypes.skills.PrimarySkillType; +import com.gmail.nossr50.datatypes.skills.SubSkillType; +import com.gmail.nossr50.util.Permissions; +import com.gmail.nossr50.util.player.UserManager; +import com.gmail.nossr50.util.random.RandomChanceUtil; +import com.gmail.nossr50.util.skills.RankUtils; +import com.gmail.nossr50.util.skills.SkillActivationType; +import com.songoda.core.compatibility.ServerVersion; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Collection; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.stream.Collectors; +import org.bukkit.block.Block; +import org.bukkit.block.BlockState; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; + +public class McMMOHandler { + + static boolean mcmmo_v2 = false; + static boolean legacy_v13 = false; + static boolean legacy_v12 = false; + static boolean legacy_v8 = false; + + static Class mcmmo_SkillType; + static Method mcmmo_SkillType_valueOf; + static Method mcmmo_SkillType_getDoubleDropsDisabled; + static Object mcmmo_ExperienceConfig_instance; + static Method mcmmo_ExperienceConfig_getXp; + static Method mcmmo_McMMOPlayer_getSkillLevel; + static Class mcmmo_PerksUtils; + static Method mcmmo_PerksUtils_handleLuckyPerks; + static Class mcmmo_SecondaryAbility; + static Method mcmmo_SecondaryAbility_valueOf; + static Method mcmmo_Permissions_secondaryAbilityEnabled; + static Method mcmmo_SkillUtils_activationSuccessful; + + static { + try { + Class.forName("com.gmail.nossr50.datatypes.skills.PrimarySkillType"); + mcmmo_v2 = true; + } catch (ClassNotFoundException ex) { + try { + mcmmo_SkillType = Class.forName("com.gmail.nossr50.datatypes.skills.SkillType"); + mcmmo_SkillType_valueOf = mcmmo_SkillType.getDeclaredMethod("valueOf", String.class); + mcmmo_SkillType_getDoubleDropsDisabled = mcmmo_SkillType.getDeclaredMethod("getDoubleDropsDisabled"); + mcmmo_ExperienceConfig_instance = ExperienceConfig.getInstance(); + mcmmo_McMMOPlayer_getSkillLevel = com.gmail.nossr50.datatypes.player.McMMOPlayer.class.getDeclaredMethod("getSkillLevel", mcmmo_SkillType); + mcmmo_PerksUtils = Class.forName("com.gmail.nossr50.util.skills.PerksUtils"); + mcmmo_PerksUtils_handleLuckyPerks = mcmmo_PerksUtils.getDeclaredMethod("handleLuckyPerks", Player.class, mcmmo_SkillType); + mcmmo_SecondaryAbility = Class.forName("com.gmail.nossr50.datatypes.skills.SecondaryAbility"); + mcmmo_SecondaryAbility_valueOf = mcmmo_SecondaryAbility.getDeclaredMethod("valueOf", String.class); + mcmmo_Permissions_secondaryAbilityEnabled = com.gmail.nossr50.util.Permissions.class.getDeclaredMethod("secondaryAbilityEnabled", Player.class, mcmmo_SecondaryAbility); + mcmmo_SkillUtils_activationSuccessful = com.gmail.nossr50.util.skills.SkillUtils.class.getDeclaredMethod("activationSuccessful", mcmmo_SecondaryAbility, Player.class, int.class, int.class); + if (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_13)) { + mcmmo_ExperienceConfig_getXp = mcmmo_ExperienceConfig_instance.getClass().getDeclaredMethod("getXp", mcmmo_SkillType, org.bukkit.block.data.BlockData.class); + legacy_v13 = true; + } else if (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_12)) { + mcmmo_ExperienceConfig_getXp = mcmmo_ExperienceConfig_instance.getClass().getDeclaredMethod("getXp", mcmmo_SkillType, org.bukkit.material.MaterialData.class); + legacy_v12 = true; + } else { + mcmmo_ExperienceConfig_getXp = mcmmo_ExperienceConfig_instance.getClass().getDeclaredMethod("getXp", mcmmo_SkillType, org.bukkit.Material.class); + legacy_v8 = true; + } + } catch (Exception ex1) { + Logger.getLogger(McMMOHandler.class.getName()).log(Level.SEVERE, "Failed to register McMMO Legacy Hook", ex1); + } + } + } + + public static void addMining(Player player, Collection blocks) { + if (player == null || blocks == null || blocks.isEmpty()) { + return; + } else if (legacy_v13 || legacy_v12 || legacy_v8) { + addBlockSkillLegacy(player, blocks, "mining"); + return; + } + ArrayList blockStates = blocks.stream().map(b -> b.getState()).collect(Collectors.toCollection(ArrayList::new)); + ExperienceAPI.addXpFromBlocksBySkill(blockStates, UserManager.getPlayer(player), PrimarySkillType.MINING); + } + + public static void addExcavation(Player player, Collection blocks) { + if (player == null || blocks == null || blocks.isEmpty()) { + return; + } else if (legacy_v13 || legacy_v12 || legacy_v8) { + addBlockSkillLegacy(player, blocks, "excavation"); + return; + } + ArrayList blockStates = blocks.stream().map(b -> b.getState()).collect(Collectors.toCollection(ArrayList::new)); + ExperienceAPI.addXpFromBlocksBySkill(blockStates, UserManager.getPlayer(player), PrimarySkillType.EXCAVATION); + } + + public static void addHerbalism(Player player, Collection blocks) { + if (player == null || blocks == null || blocks.isEmpty()) { + return; + } else if (legacy_v13 || legacy_v12 || legacy_v8) { + addBlockSkillLegacy(player, blocks, "herbalism"); + return; + } + ArrayList blockStates = blocks.stream().map(b -> b.getState()).collect(Collectors.toCollection(ArrayList::new)); + ExperienceAPI.addXpFromBlocksBySkill(blockStates, UserManager.getPlayer(player), PrimarySkillType.HERBALISM); + } + + public static void addWoodcutting(Player player, Collection blocks) { + if (player == null || blocks == null || blocks.isEmpty()) { + return; + } else if (legacy_v13 || legacy_v12 || legacy_v8) { + addBlockSkillLegacy(player, blocks, "woodcutting"); + return; + } + ArrayList blockStates = blocks.stream().map(b -> b.getState()).collect(Collectors.toCollection(ArrayList::new)); + ExperienceAPI.addXpFromBlocksBySkill(blockStates, UserManager.getPlayer(player), PrimarySkillType.WOODCUTTING); + } + + public static int getAcrobaticsSkill(Player player) { + if (player == null) { + return -1; + } else if (legacy_v13 || legacy_v12 || legacy_v8) { + return getSkillLegacy(player, "acrobatics"); + } + return UserManager.getPlayer(player).getSkillLevel(PrimarySkillType.ACROBATICS); + } + + public static int getAlchemySkill(Player player) { + if (player == null) { + return -1; + } else if (legacy_v13 || legacy_v12 || legacy_v8) { + return getSkillLegacy(player, "alchemy"); + } + return UserManager.getPlayer(player).getSkillLevel(PrimarySkillType.ALCHEMY); + } + + public static int getArcherySkill(Player player) { + if (player == null) { + return -1; + } else if (legacy_v13 || legacy_v12 || legacy_v8) { + return getSkillLegacy(player, "archery"); + } + return UserManager.getPlayer(player).getSkillLevel(PrimarySkillType.ARCHERY); + } + + public static int getAxesSkill(Player player) { + if (player == null) { + return -1; + } else if (legacy_v13 || legacy_v12 || legacy_v8) { + return getSkillLegacy(player, "axes"); + } + return UserManager.getPlayer(player).getSkillLevel(PrimarySkillType.AXES); + } + + public static int getExcavationSkill(Player player) { + if (player == null) { + return -1; + } else if (legacy_v13 || legacy_v12 || legacy_v8) { + return getSkillLegacy(player, "excavation"); + } + return UserManager.getPlayer(player).getSkillLevel(PrimarySkillType.EXCAVATION); + } + + public static int getFishingSkill(Player player) { + if (player == null) { + return -1; + } else if (legacy_v13 || legacy_v12 || legacy_v8) { + return getSkillLegacy(player, "fishing"); + } + return UserManager.getPlayer(player).getSkillLevel(PrimarySkillType.FISHING); + } + + public static int getHerbalismSkill(Player player) { + if (player == null) { + return -1; + } else if (legacy_v13 || legacy_v12 || legacy_v8) { + return getSkillLegacy(player, "herbalism"); + } + return UserManager.getPlayer(player).getSkillLevel(PrimarySkillType.HERBALISM); + } + + public static int getMiningSkill(Player player) { + if (player == null) { + return -1; + } else if (legacy_v13 || legacy_v12 || legacy_v8) { + return getSkillLegacy(player, "mining"); + } + return UserManager.getPlayer(player).getSkillLevel(PrimarySkillType.MINING); + } + + public static int getRepairSkill(Player player) { + if (player == null) { + return -1; + } else if (legacy_v13 || legacy_v12 || legacy_v8) { + return getSkillLegacy(player, "repair"); + } + return UserManager.getPlayer(player).getSkillLevel(PrimarySkillType.REPAIR); + } + + public static int getSmeltingSkill(Player player) { + if (player == null) { + return -1; + } else if (legacy_v13 || legacy_v12 || legacy_v8) { + return getSkillLegacy(player, "smelting"); + } + return UserManager.getPlayer(player).getSkillLevel(PrimarySkillType.SMELTING); + } + + public static int getSwordsSkill(Player player) { + if (player == null) { + return -1; + } else if (legacy_v13 || legacy_v12 || legacy_v8) { + return getSkillLegacy(player, "swords"); + } + return UserManager.getPlayer(player).getSkillLevel(PrimarySkillType.SWORDS); + } + + public static int getTamingSkill(Player player) { + if (player == null) { + return -1; + } else if (legacy_v13 || legacy_v12 || legacy_v8) { + return getSkillLegacy(player, "taming"); + } + return UserManager.getPlayer(player).getSkillLevel(PrimarySkillType.TAMING); + } + + public static int getUnarmedSkill(Player player) { + if (player == null) { + return -1; + } else if (legacy_v13 || legacy_v12 || legacy_v8) { + return getSkillLegacy(player, "unarmed"); + } + return UserManager.getPlayer(player).getSkillLevel(PrimarySkillType.UNARMED); + } + + public static int getWoodcuttingSkill(Player player) { + if (player == null) { + return -1; + } else if (legacy_v13 || legacy_v12 || legacy_v8) { + return getSkillLegacy(player, "woodcutting"); + } + return UserManager.getPlayer(player).getSkillLevel(PrimarySkillType.WOODCUTTING); + } + + public static void addAcrobatics(Player player, int xp) { + if (player == null) { + return; + } else if (legacy_v13 || legacy_v12 || legacy_v8) { + ExperienceAPI.addXP(player, "acrobatics", xp); + } + UserManager.getPlayer(player).beginXpGain(PrimarySkillType.ACROBATICS, xp, XPGainReason.UNKNOWN, XPGainSource.CUSTOM); + } + + public static void addAlchemy(Player player, int xp) { + if (player == null) { + return; + } else if (legacy_v13 || legacy_v12 || legacy_v8) { + ExperienceAPI.addXP(player, "alchemy", xp); + } + UserManager.getPlayer(player).beginXpGain(PrimarySkillType.ALCHEMY, xp, XPGainReason.UNKNOWN, XPGainSource.CUSTOM); + } + + public static void addArchery(Player player, int xp) { + if (player == null) { + return; + } else if (legacy_v13 || legacy_v12 || legacy_v8) { + ExperienceAPI.addXP(player, "archery", xp); + } + UserManager.getPlayer(player).beginXpGain(PrimarySkillType.ARCHERY, xp, XPGainReason.UNKNOWN, XPGainSource.CUSTOM); + } + + public static void addAxes(Player player, int xp) { + if (player == null) { + return; + } else if (legacy_v13 || legacy_v12 || legacy_v8) { + ExperienceAPI.addXP(player, "axes", xp); + } + UserManager.getPlayer(player).beginXpGain(PrimarySkillType.AXES, xp, XPGainReason.UNKNOWN, XPGainSource.CUSTOM); + } + + public static void addExcavation(Player player, int xp) { + if (player == null) { + return; + } else if (legacy_v13 || legacy_v12 || legacy_v8) { + ExperienceAPI.addXP(player, "excavation", xp); + } + UserManager.getPlayer(player).beginXpGain(PrimarySkillType.EXCAVATION, xp, XPGainReason.UNKNOWN, XPGainSource.CUSTOM); + } + + public static void addFishing(Player player, int xp) { + if (player == null) { + return; + } else if (legacy_v13 || legacy_v12 || legacy_v8) { + ExperienceAPI.addXP(player, "fishing", xp); + } + UserManager.getPlayer(player).beginXpGain(PrimarySkillType.FISHING, xp, XPGainReason.UNKNOWN, XPGainSource.CUSTOM); + } + + public static void addHerbalism(Player player, int xp) { + if (player == null) { + return; + } else if (legacy_v13 || legacy_v12 || legacy_v8) { + ExperienceAPI.addXP(player, "herbalism", xp); + } + UserManager.getPlayer(player).beginXpGain(PrimarySkillType.HERBALISM, xp, XPGainReason.UNKNOWN, XPGainSource.CUSTOM); + } + + public static void addMining(Player player, int xp) { + if (player == null) { + return; + } else if (legacy_v13 || legacy_v12 || legacy_v8) { + ExperienceAPI.addXP(player, "mining", xp); + } + UserManager.getPlayer(player).beginXpGain(PrimarySkillType.MINING, xp, XPGainReason.UNKNOWN, XPGainSource.CUSTOM); + } + + public static void addRepair(Player player, int xp) { + if (player == null) { + return; + } else if (legacy_v13 || legacy_v12 || legacy_v8) { + ExperienceAPI.addXP(player, "repair", xp); + } + UserManager.getPlayer(player).beginXpGain(PrimarySkillType.REPAIR, xp, XPGainReason.UNKNOWN, XPGainSource.CUSTOM); + } + + public static void addSmelting(Player player, int xp) { + if (player == null) { + return; + } else if (legacy_v13 || legacy_v12 || legacy_v8) { + ExperienceAPI.addXP(player, "smelting", xp); + } + UserManager.getPlayer(player).beginXpGain(PrimarySkillType.SMELTING, xp, XPGainReason.UNKNOWN, XPGainSource.CUSTOM); + } + + public static void addSwords(Player player, int xp) { + if (player == null) { + return; + } else if (legacy_v13 || legacy_v12 || legacy_v8) { + ExperienceAPI.addXP(player, "swords", xp); + } + UserManager.getPlayer(player).beginXpGain(PrimarySkillType.SWORDS, xp, XPGainReason.UNKNOWN, XPGainSource.CUSTOM); + } + + public static void addTaming(Player player, int xp) { + if (player == null) { + return; + } else if (legacy_v13 || legacy_v12 || legacy_v8) { + ExperienceAPI.addXP(player, "taming", xp); + } + UserManager.getPlayer(player).beginXpGain(PrimarySkillType.TAMING, xp, XPGainReason.UNKNOWN, XPGainSource.CUSTOM); + } + + public static void addUnarmed(Player player, int xp) { + if (player == null) { + return; + } else if (legacy_v13 || legacy_v12 || legacy_v8) { + ExperienceAPI.addXP(player, "unarmed", xp); + } + UserManager.getPlayer(player).beginXpGain(PrimarySkillType.UNARMED, xp, XPGainReason.UNKNOWN, XPGainSource.CUSTOM); + } + + public static void addWoodcutting(Player player, int xp) { + if (player == null) { + return; + } else if (legacy_v13 || legacy_v12 || legacy_v8) { + ExperienceAPI.addXP(player, "woodcutting", xp); + } + UserManager.getPlayer(player).beginXpGain(PrimarySkillType.WOODCUTTING, xp, XPGainReason.UNKNOWN, XPGainSource.CUSTOM); + } + + public static boolean hasHerbalismDoubleDrops(Player player) { + if (legacy_v13 || legacy_v12 || legacy_v8) { + return hasBlockDoubleLegacy(player, "herbalism"); + } + + if (PrimarySkillType.HERBALISM.getDoubleDropsDisabled()) { + return false; + } + + return Permissions.isSubSkillEnabled(player, SubSkillType.HERBALISM_DOUBLE_DROPS) + && RankUtils.hasReachedRank(1, player, SubSkillType.HERBALISM_DOUBLE_DROPS) + && RandomChanceUtil.isActivationSuccessful(SkillActivationType.RANDOM_LINEAR_100_SCALE_WITH_CAP, SubSkillType.HERBALISM_DOUBLE_DROPS, player); + } + + public static boolean hasMiningDoubleDrops(Player player) { + if (legacy_v13 || legacy_v12 || legacy_v8) { + return hasBlockDoubleLegacy(player, "mining"); + } + + if (PrimarySkillType.MINING.getDoubleDropsDisabled()) { + return false; + } + + return Permissions.isSubSkillEnabled(player, SubSkillType.MINING_DOUBLE_DROPS) + && RankUtils.hasReachedRank(1, player, SubSkillType.MINING_DOUBLE_DROPS) + && RandomChanceUtil.isActivationSuccessful(SkillActivationType.RANDOM_LINEAR_100_SCALE_WITH_CAP, SubSkillType.MINING_DOUBLE_DROPS, player); + } + + public static boolean hasWoodcuttingDoubleDrops(Player player) { + if (legacy_v13 || legacy_v12 || legacy_v8) { + return hasBlockDoubleLegacy(player, "woodcutting"); + } + + if (PrimarySkillType.WOODCUTTING.getDoubleDropsDisabled()) { + return false; + } + + return Permissions.isSubSkillEnabled(player, SubSkillType.WOODCUTTING_HARVEST_LUMBER) + && RankUtils.hasReachedRank(1, player, SubSkillType.WOODCUTTING_HARVEST_LUMBER) + && RandomChanceUtil.isActivationSuccessful(SkillActivationType.RANDOM_LINEAR_100_SCALE_WITH_CAP, SubSkillType.WOODCUTTING_HARVEST_LUMBER, player); + } + + public static boolean isUsingBerserk(Player player) { + return AbilityAPI.berserkEnabled(player); + } + + public static boolean isUsingGigaDrill(Player player) { + return AbilityAPI.gigaDrillBreakerEnabled(player); + } + + public static boolean isUsingGreenTerra(Player player) { + return AbilityAPI.greenTerraEnabled(player); + } + + public static boolean isUsingSerratedStrikes(Player player) { + return AbilityAPI.serratedStrikesEnabled(player); + } + + public static boolean isUsingSkullSplitter(Player player) { + return AbilityAPI.skullSplitterEnabled(player); + } + + public static boolean isUsingSuperBreaker(Player player) { + return AbilityAPI.superBreakerEnabled(player); + } + + public static boolean isUsingTreeFeller(Player player) { + return AbilityAPI.treeFellerEnabled(player); + } + + public static boolean isBleeding(LivingEntity victim) { + return AbilityAPI.isBleeding(victim); + } + + /** + * woodcutting, mining, herbalism + */ + protected static boolean hasBlockDoubleLegacy(Player player, String skill) { + if (player.hasMetadata("mcMMO: Player Data")) { + try { + Object skillType = mcmmo_SkillType_valueOf.invoke(null, skill.toUpperCase()); + if ((boolean) mcmmo_SkillType_getDoubleDropsDisabled.invoke(skillType)) { + return false; + } + + int skillLevel = (int) mcmmo_McMMOPlayer_getSkillLevel.invoke(UserManager.getPlayer(player), skillType); + int activationChance = (int) mcmmo_PerksUtils_handleLuckyPerks.invoke(null, player, skillType); + + Object secondaryDouble = mcmmo_SecondaryAbility_valueOf.invoke(null, skill.toUpperCase() + "_DOUBLE_DROPS"); + if (!((boolean) mcmmo_Permissions_secondaryAbilityEnabled.invoke(null, player, secondaryDouble))) { + return false; + } + return (boolean) mcmmo_SkillUtils_activationSuccessful.invoke(null, secondaryDouble, player, skillLevel, activationChance); + + } catch (Exception ex1) { + Logger.getLogger(McMMOHandler.class.getName()).log(Level.SEVERE, "Failed to invoke McMMO Legacy Hook", ex1); + } + } + return false; + } + + protected static void addBlockSkillLegacy(Player player, Collection blocks, String skill) { + try { + Object skillType = mcmmo_SkillType_valueOf.invoke(null, skill.toUpperCase()); + + int xp = 0; + for (Block block : blocks) { + xp += (int) mcmmo_ExperienceConfig_getXp.invoke(mcmmo_ExperienceConfig_instance, skillType, legacy_getBlock(block)); + } + + ExperienceAPI.addXP(player, skill, xp); + } catch (Exception ex1) { + Logger.getLogger(McMMOHandler.class.getName()).log(Level.SEVERE, "Failed to invoke McMMO Legacy Hook", ex1); + } + } + + protected static Object legacy_getBlock(Block block) { + if (legacy_v13) { + return block.getBlockData(); + } else if (legacy_v12) { + return block.getState().getData(); + } else { + return block.getType(); + } + } + + protected static int getSkillLegacy(Player player, String skill) { + if (player.hasMetadata("mcMMO: Player Data")) { + try { + Object skillType = mcmmo_SkillType_valueOf.invoke(null, skill.toUpperCase()); + return (int) mcmmo_McMMOPlayer_getSkillLevel.invoke(UserManager.getPlayer(player), skillType); + } catch (Exception ex1) { + Logger.getLogger(McMMOHandler.class.getName()).log(Level.SEVERE, "Failed to invoke McMMO Legacy Hook", ex1); + } + } + return 0; + } + +} From fa7d5a5974547c04085b49637954f948cb63a37a Mon Sep 17 00:00:00 2001 From: jascotty2 Date: Wed, 9 Oct 2019 19:52:46 -0500 Subject: [PATCH 19/21] add stacker methods to get min entity stack --- .../songoda/core/hooks/stackers/StackMob.java | 7 +++++++ .../songoda/core/hooks/stackers/Stacker.java | 4 ++++ .../core/hooks/stackers/UltimateStacker.java | 7 +++++++ .../core/hooks/stackers/WildStacker.java | 18 ++++++++++++++++++ 4 files changed, 36 insertions(+) diff --git a/Core/src/main/java/com/songoda/core/hooks/stackers/StackMob.java b/Core/src/main/java/com/songoda/core/hooks/stackers/StackMob.java index d652a52b..19897f41 100644 --- a/Core/src/main/java/com/songoda/core/hooks/stackers/StackMob.java +++ b/Core/src/main/java/com/songoda/core/hooks/stackers/StackMob.java @@ -1,6 +1,7 @@ package com.songoda.core.hooks.stackers; import org.bukkit.Bukkit; +import org.bukkit.entity.EntityType; import org.bukkit.entity.Item; import org.bukkit.entity.LivingEntity; import uk.antiperson.stackmob.api.EntityManager; @@ -72,4 +73,10 @@ public class StackMob extends Stacker { StackedEntity stackedEntity = plugin.getStackedEntity(entity); stackedEntity.setSize(stackedEntity.getSize() + amount); } + + @Override + public int minimumEntityStack(EntityType type) { + return 0; + } + } diff --git a/Core/src/main/java/com/songoda/core/hooks/stackers/Stacker.java b/Core/src/main/java/com/songoda/core/hooks/stackers/Stacker.java index baf2b60c..b00bed03 100644 --- a/Core/src/main/java/com/songoda/core/hooks/stackers/Stacker.java +++ b/Core/src/main/java/com/songoda/core/hooks/stackers/Stacker.java @@ -1,6 +1,7 @@ package com.songoda.core.hooks.stackers; import com.songoda.core.hooks.Hook; +import org.bukkit.entity.EntityType; import org.bukkit.entity.Item; import org.bukkit.entity.LivingEntity; @@ -29,4 +30,7 @@ public abstract class Stacker implements Hook { } public abstract void add(LivingEntity entity, int amount); + + public abstract int minimumEntityStack(EntityType type); + } diff --git a/Core/src/main/java/com/songoda/core/hooks/stackers/UltimateStacker.java b/Core/src/main/java/com/songoda/core/hooks/stackers/UltimateStacker.java index 396c4bb0..7424f67a 100644 --- a/Core/src/main/java/com/songoda/core/hooks/stackers/UltimateStacker.java +++ b/Core/src/main/java/com/songoda/core/hooks/stackers/UltimateStacker.java @@ -3,8 +3,10 @@ package com.songoda.core.hooks.stackers; import com.songoda.ultimatestacker.entity.EntityStack; import com.songoda.ultimatestacker.utils.Methods; import java.lang.reflect.Method; +import org.bukkit.entity.EntityType; import org.bukkit.entity.Item; import org.bukkit.entity.LivingEntity; +import org.bukkit.plugin.Plugin; public class UltimateStacker extends Stacker { @@ -80,4 +82,9 @@ public class UltimateStacker extends Stacker { public void add(LivingEntity entity, int amount) { plugin.getEntityStackManager().getStack(entity).addAmount(amount); } + + @Override + public int minimumEntityStack(EntityType type) { + return ((Plugin) plugin).getConfig().getInt("Entities.Min Stack Amount"); + } } diff --git a/Core/src/main/java/com/songoda/core/hooks/stackers/WildStacker.java b/Core/src/main/java/com/songoda/core/hooks/stackers/WildStacker.java index 5c037ea6..8be301cd 100644 --- a/Core/src/main/java/com/songoda/core/hooks/stackers/WildStacker.java +++ b/Core/src/main/java/com/songoda/core/hooks/stackers/WildStacker.java @@ -2,11 +2,19 @@ package com.songoda.core.hooks.stackers; import com.bgsoftware.wildstacker.api.WildStackerAPI; import com.bgsoftware.wildstacker.api.objects.StackedEntity; +import org.bukkit.entity.EntityType; import org.bukkit.entity.Item; import org.bukkit.entity.LivingEntity; +import org.bukkit.plugin.Plugin; public class WildStacker extends Stacker { + final Plugin plugin; + + public WildStacker(Plugin plugin) { + this.plugin = plugin; + } + @Override public String getName() { return "WildStacker"; @@ -58,4 +66,14 @@ public class WildStacker extends Stacker { StackedEntity stackedEntity = WildStackerAPI.getStackedEntity(entity); stackedEntity.setStackAmount(stackedEntity.getStackAmount() + amount, true); } + + @Override + public int minimumEntityStack(EntityType type) { + int min = plugin.getConfig().getInt("entities.minimum-limits." + type.name(), -1); + if (min == -1) { + min = plugin.getConfig().getInt("entities.minimum-limits.all", -1); + } + return min == -1 ? 0 : min; + } + } From 3474ddeb8f46d4fadf76a7914581aa21e3fc260e Mon Sep 17 00:00:00 2001 From: jascotty2 Date: Wed, 9 Oct 2019 20:03:16 -0500 Subject: [PATCH 20/21] simplify points hook init --- .../songoda/core/hooks/economies/PlayerPointsEconomy.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Core/src/main/java/com/songoda/core/hooks/economies/PlayerPointsEconomy.java b/Core/src/main/java/com/songoda/core/hooks/economies/PlayerPointsEconomy.java index 8856ebb2..ea0453a9 100644 --- a/Core/src/main/java/com/songoda/core/hooks/economies/PlayerPointsEconomy.java +++ b/Core/src/main/java/com/songoda/core/hooks/economies/PlayerPointsEconomy.java @@ -1,15 +1,15 @@ package com.songoda.core.hooks.economies; import org.black_ixx.playerpoints.PlayerPoints; -import org.bukkit.Bukkit; import org.bukkit.OfflinePlayer; +import org.bukkit.plugin.Plugin; public class PlayerPointsEconomy extends Economy { private final PlayerPoints playerPoints; - public PlayerPointsEconomy() { - this.playerPoints = (PlayerPoints) Bukkit.getServer().getPluginManager().getPlugin("PlayerPoints"); + public PlayerPointsEconomy(Plugin plugin) { + this.playerPoints = (PlayerPoints) plugin; } private int convertAmount(double amount) { From 27260ab30f109d58cfdc82907ac714be1643fd2b Mon Sep 17 00:00:00 2001 From: jascotty2 Date: Wed, 9 Oct 2019 20:04:10 -0500 Subject: [PATCH 21/21] Version 2.2.1 --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index ed8f223e..63de579d 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -4,7 +4,7 @@ stages: variables: name: "SongodaCore" path: "/builds/$CI_PROJECT_PATH" - version: "2.2.0" + version: "2.2.1" build: stage: build