From e4fd341853f10df7bff4adaf5b5d42a8219bffff Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sun, 9 Jul 2023 13:56:57 -0400 Subject: [PATCH 001/151] Fixed an issue where the setting isAutoFeaturesEnabled was not being applied to the permissions which resulted in the perms always being enabled when OPd. --- docs/changelog_v3.3.x.md | 4 +++- .../prison/spigot/autofeatures/AutoManagerFeatures.java | 9 +++++---- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 837761593..a966e2b37 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -14,9 +14,11 @@ These change logs represent the work that has been going on within prison. -# 3.3.0-alpha.15 2023-07-07 +# 3.3.0-alpha.15 2023-07-09 +* **Fixed an issue where the setting isAutoFeaturesEnabled was not being applied to the permissions which resulted in the perms always being enabled when OPd.** + * **2023-07-07 v3.3.0-alpha.15 Released** diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerFeatures.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerFeatures.java index 841fbae06..5cb7def89 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerFeatures.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerFeatures.java @@ -470,12 +470,13 @@ private int applyAutoEventsDetails( PrisonMinesBlockBreakEvent pmEvent ) { boolean loreSmelt = isLoreEnabled && checkLore( itemInHand, getMessage( AutoFeatures.loreSmeltValue) ); boolean loreBlock = isLoreEnabled && checkLore( itemInHand, getMessage( AutoFeatures.loreBlockValue ) ); - boolean permPickup = player.isPermissionSet( getMessage( AutoFeatures.permissionAutoPickup )); - boolean permSmelt = player.isPermissionSet( getMessage( AutoFeatures.permissionAutoSmelt )); - boolean permBlock = player.isPermissionSet( getMessage( AutoFeatures.permissionAutoBlock )); - boolean isAutoFeaturesEnabled = isBoolean( AutoFeatures.isAutoFeaturesEnabled ); + boolean permPickup = isAutoFeaturesEnabled && player.isPermissionSet( getMessage( AutoFeatures.permissionAutoPickup )); + boolean permSmelt = isAutoFeaturesEnabled && player.isPermissionSet( getMessage( AutoFeatures.permissionAutoSmelt )); + boolean permBlock = isAutoFeaturesEnabled && player.isPermissionSet( getMessage( AutoFeatures.permissionAutoBlock )); + + boolean configPickup = isAutoFeaturesEnabled && isBoolean( AutoFeatures.autoPickupEnabled ); boolean configSmelt = isAutoFeaturesEnabled && isBoolean( AutoFeatures.autoSmeltEnabled ); boolean configBlock = isAutoFeaturesEnabled && isBoolean( AutoFeatures.autoBlockEnabled ); From 903f425e67c1cfd89b018916c4f74e77d0e2341d Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sun, 9 Jul 2023 14:00:07 -0400 Subject: [PATCH 002/151] doc update --- docs/prison_changelog_v3.3.0-alpha.15.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/docs/prison_changelog_v3.3.0-alpha.15.md b/docs/prison_changelog_v3.3.0-alpha.15.md index 80f7b0ef7..21d8d1fcb 100644 --- a/docs/prison_changelog_v3.3.0-alpha.15.md +++ b/docs/prison_changelog_v3.3.0-alpha.15.md @@ -16,7 +16,11 @@ These build logs represent the work that has been going on within prison. The following is a highlight of changes for the alpha.15 release since the alpha.14 release. --Full support for 1.20.x including the heights and blocks. +- Full support for 1.20.x including the heights and blocks. + + +- Added support for Java 20. + - MineBombs - Added a new field specifically for use with item names which supports color codes. @@ -45,7 +49,7 @@ The following is a highlight of changes for the alpha.15 release since the alpha - Fixed how NBT-api is being shadowed and used to get it to work properly with Spigot 1.20.x. -- Minor fixes and enchancements: blockEvents, autoFeatures and monitor priorities, GUI Player Mine config options, prevent GUI configs from loading twice, when mining now can control non-prison placed blocks to pass through to be handled by bukkit, fix autosell when disabled, hooked up support for minecraft stats to track block mining, prevent zero drops if calcs are less than 1, fix sellall trying to sell an invalid stack, fix prison utils potion effects when no player is provided, support for ExaltedEconomy, able to bypass adding new players on startup, updated Prison's jar reporter to identify Java versions 19, 20, and 21, clearified help on `/rankup` and `/presetige`, update of how topN is being processed, added topN stats which reports some of the core info. +- Minor fixes and enhancements: blockEvents, autoFeatures and monitor priorities, GUI Player Mine config options, prevent GUI configs from loading twice, when mining now can control non-prison placed blocks to pass through to be handled by bukkit, fix autosell when disabled, hooked up support for minecraft stats to track block mining, prevent zero drops if calcs are less than 1, fix sellall trying to sell an invalid stack, fix prison utils potion effects when no player is provided, support for ExaltedEconomy, able to bypass adding new players on startup, updated Prison's jar reporter to identify Java versions 19, 20, and 21, clarified help on `/rankup` and `/presetige`, update of how topN is being processed, added topN stats which reports some of the core info. From 65589703223f6dd355af24431de45093ae61a738 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sun, 9 Jul 2023 14:04:32 -0400 Subject: [PATCH 003/151] Fixed an issue with prison commands being remapped, but other commands within prison were not using them. This tries to find the remapped command for all commands by updating the SpigotCommandSender.dispatchCommand(). --- docs/changelog_v3.3.x.md | 4 ++++ .../commands/PrisonSpigotBackpackCommands.java | 5 +++-- .../commands/PrisonSpigotSellAllCommands.java | 15 +++++++++------ .../prison/spigot/game/SpigotCommandSender.java | 10 +++++++++- 4 files changed, 25 insertions(+), 9 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index a966e2b37..e0dac0d3c 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -17,6 +17,10 @@ These change logs represent the work that has been going on within prison. # 3.3.0-alpha.15 2023-07-09 +* **Fixed an issue with prison commands being remapped, but other commands within prison were not using them.** +This tries to find the remapped command for all commands by updating the SpigotCommandSender.dispatchCommand(). + + * **Fixed an issue where the setting isAutoFeaturesEnabled was not being applied to the permissions which resulted in the perms always being enabled when OPd.** diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/commands/PrisonSpigotBackpackCommands.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/commands/PrisonSpigotBackpackCommands.java index 4d07b0d54..403baa225 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/commands/PrisonSpigotBackpackCommands.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/commands/PrisonSpigotBackpackCommands.java @@ -29,8 +29,9 @@ private void backpackMainCommand(CommandSender sender, description = "Leave empty if you want to open your main backpack, add an ID if you've more than one.") String id){ if (sender.hasPermission("prison.admin") || sender.isOp()){ - String registeredCmd = Prison.get().getCommandHandler().findRegisteredCommand("backpack help"); - sender.dispatchCommand(registeredCmd); + sender.dispatchCommand("backpack help"); +// String registeredCmd = Prison.get().getCommandHandler().findRegisteredCommand("backpack help"); +// sender.dispatchCommand(registeredCmd); return; } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/commands/PrisonSpigotSellAllCommands.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/commands/PrisonSpigotSellAllCommands.java index 9bb582477..4345aeb55 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/commands/PrisonSpigotSellAllCommands.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/commands/PrisonSpigotSellAllCommands.java @@ -91,11 +91,13 @@ private void sellAllCommands(CommandSender sender) { if (!isEnabled()) return; if (sender.hasPermission("prison.admin")) { - String registeredCmd = Prison.get().getCommandHandler().findRegisteredCommand( "sellall help" ); - sender.dispatchCommand(registeredCmd); + sender.dispatchCommand("sellall help"); +// String registeredCmd = Prison.get().getCommandHandler().findRegisteredCommand( "sellall help" ); +// sender.dispatchCommand(registeredCmd); } else { - String registeredCmd = Prison.get().getCommandHandler().findRegisteredCommand( "sellall sell" ); - sender.dispatchCommand(registeredCmd); + sender.dispatchCommand("sellall sell"); +// String registeredCmd = Prison.get().getCommandHandler().findRegisteredCommand( "sellall sell" ); +// sender.dispatchCommand(registeredCmd); } } @@ -834,8 +836,9 @@ private void sellAllToolsTriggerToggle(CommandSender sender, if (!isEnabled()) return; if (enable.equalsIgnoreCase("null")){ - String registeredCmd = Prison.get().getCommandHandler().findRegisteredCommand( "sellall toolsTrigger help" ); - sender.dispatchCommand(registeredCmd); + sender.dispatchCommand("sellall toolsTrigger help"); +// String registeredCmd = Prison.get().getCommandHandler().findRegisteredCommand( "sellall toolsTrigger help" ); +// sender.dispatchCommand(registeredCmd); return; } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotCommandSender.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotCommandSender.java index 26bbb66d4..f3f1ca8d6 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotCommandSender.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotCommandSender.java @@ -61,8 +61,16 @@ public String getName() { return bukkitSender.getName(); } + /** + *

This function will dispatch a command and run it as command sender. + * But before it is ran, this function looks up within the Prison command handler + * to see if it's commands have been remapped to another command, and if it has, + * it then uses the mapped command. + *

+ */ @Override public void dispatchCommand(String command) { - Bukkit.getServer().dispatchCommand(bukkitSender, command); + String registeredCmd = Prison.get().getCommandHandler().findRegisteredCommand( command ); + Bukkit.getServer().dispatchCommand(bukkitSender, registeredCmd); } @Override public boolean doesSupportColors() { From db7351259b09ecaac8d78d193ce3ad1ea4ad8be3 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Mon, 10 Jul 2023 19:24:24 -0400 Subject: [PATCH 004/151] Setup a way to pull a config's hash keys. These would be used to dynamically get all settings within a hash. --- docs/changelog_v3.3.x.md | 6 +++++- .../tech/mcprison/prison/file/JsonFileIO.java | 7 +++++++ .../prison/internal/platform/Platform.java | 9 ++++++++ .../tech/mcprison/prison/TestPlatform.java | 13 ++++++++++++ .../prison/spigot/SpigotPlatform.java | 21 +++++++++++++++++++ 5 files changed, 55 insertions(+), 1 deletion(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index e0dac0d3c..0428085fc 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -14,7 +14,11 @@ These change logs represent the work that has been going on within prison. -# 3.3.0-alpha.15 2023-07-09 +# 3.3.0-alpha.15 2023-07-10 + + +* **Setup a way to pull a config's hash keys.** +These would be used to dynamically get all settings within a hash. * **Fixed an issue with prison commands being remapped, but other commands within prison were not using them.** diff --git a/prison-core/src/main/java/tech/mcprison/prison/file/JsonFileIO.java b/prison-core/src/main/java/tech/mcprison/prison/file/JsonFileIO.java index 55e23a387..b2deb33dc 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/file/JsonFileIO.java +++ b/prison-core/src/main/java/tech/mcprison/prison/file/JsonFileIO.java @@ -89,6 +89,13 @@ private static String getFileNamePrefix( String UUIDString ) { return UUIDString.substring( 0, 14 ); } + + public String toString( Object obj ) { + String json = getGson().toJson( obj ); + + return json; + } + /** * This function will save a file as a JSON format. It will first save it as a * temp file to make sure the data can be written to the file system, then once diff --git a/prison-core/src/main/java/tech/mcprison/prison/internal/platform/Platform.java b/prison-core/src/main/java/tech/mcprison/prison/internal/platform/Platform.java index 479f4be6d..e4479d38d 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/internal/platform/Platform.java +++ b/prison-core/src/main/java/tech/mcprison/prison/internal/platform/Platform.java @@ -303,6 +303,15 @@ public default Optional getCommand(String label) { public double getConfigDouble( String key, double defaultValue ); + /** + *

Given the path to a hash, this will return all of the keys within + * the hash at the root level. It will not traverse deeper. + * The list of keys can then be used to access all of the values. + *

+ * + */ + public List getConfigHashKeys(String hashPrefix); + public boolean isWorldExcluded( String worldName ); diff --git a/prison-core/src/test/java/tech/mcprison/prison/TestPlatform.java b/prison-core/src/test/java/tech/mcprison/prison/TestPlatform.java index 6875c4201..cdef3f149 100644 --- a/prison-core/src/test/java/tech/mcprison/prison/TestPlatform.java +++ b/prison-core/src/test/java/tech/mcprison/prison/TestPlatform.java @@ -299,6 +299,19 @@ public List getConfigStringArray( String key ) { return new ArrayList(); } + /** + *

Given the path to a hash, this will return all of the keys within + * the hash at the root level. It will not traverse deeper. + * The list of keys can then be used to access all of the values. + *

+ * + */ + @Override + public List getConfigHashKeys(String hashPrefix) { + return new ArrayList(); + } + + @Override public boolean isWorldExcluded( String worldName ) { return false; diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/SpigotPlatform.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/SpigotPlatform.java index c560ec3a9..f5b7758f5 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/SpigotPlatform.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/SpigotPlatform.java @@ -42,6 +42,7 @@ import org.bukkit.command.CommandSender; import org.bukkit.command.ConsoleCommandSender; import org.bukkit.command.SimpleCommandMap; +import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.event.EventPriority; import org.bukkit.event.player.AsyncPlayerChatEvent; @@ -1062,6 +1063,26 @@ public double getConfigDouble( String key, double defaultValue ) { return results; } + /** + *

Given the path to a hash, this will return all of the keys within + * the hash at the root level. It will not traverse deeper. + * The list of keys can then be used to access all of the values. + *

+ * + */ + @Override + public List getConfigHashKeys( String hashPrefix ) { + List keys = new ArrayList<>(); + + ConfigurationSection configSection = + SpigotPrison.getInstance().getConfig().getConfigurationSection( hashPrefix ); + + if ( configSection != null ) { + keys.addAll( configSection.getKeys(false) ); + } + + return keys; + } @Override public boolean isWorldExcluded( String worldName ) { From 28c37b2e8ba890da9c668de9c3c4abe35fb16fab Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Mon, 10 Jul 2023 19:27:50 -0400 Subject: [PATCH 005/151] Start to setup support for WorldEdit and WorldGuard. --- build.gradle | 5 + docs/changelog_v3.3.x.md | 3 + .../prison/worldguard/PrisonWorldEdit.java | 5 + .../prison/worldguard/PrisonWorldGuard.java | 5 + prison-spigot/build.gradle | 24 +++ .../spigot/worldguard/WorldGuardData.java | 155 ++++++++++++++++++ .../spigot/worldguard/WorldGuardSettings.java | 64 ++++++++ prison-worldguard6/build.gradle | 123 ++++++++++++++ .../worldguard/PrisonWorldEdit6.java | 28 ++++ .../worldguard/PrisonWorldGuard6.java | 14 ++ prison-worldguard7/build.gradle | 85 ++++++++++ 11 files changed, 511 insertions(+) create mode 100644 prison-core/src/main/java/tech/mcprison/prison/worldguard/PrisonWorldEdit.java create mode 100644 prison-core/src/main/java/tech/mcprison/prison/worldguard/PrisonWorldGuard.java create mode 100644 prison-spigot/src/main/java/tech/mcprison/prison/spigot/worldguard/WorldGuardData.java create mode 100644 prison-spigot/src/main/java/tech/mcprison/prison/spigot/worldguard/WorldGuardSettings.java create mode 100644 prison-worldguard6/build.gradle create mode 100644 prison-worldguard6/src/main/java/tech/mcprison/worldguard6/worldguard/PrisonWorldEdit6.java create mode 100644 prison-worldguard6/src/main/java/tech/mcprison/worldguard6/worldguard/PrisonWorldGuard6.java create mode 100644 prison-worldguard7/build.gradle diff --git a/build.gradle b/build.gradle index 8e7504ecf..2e940621c 100644 --- a/build.gradle +++ b/build.gradle @@ -127,6 +127,11 @@ subprojects { includeGroup 'org.apache.commons' } } + + maven { + url "https://mvnrepository.com/artifact" + + } } diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 0428085fc..fcb92d60f 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -17,6 +17,9 @@ These change logs represent the work that has been going on within prison. # 3.3.0-alpha.15 2023-07-10 +* **Start to setup support for WorldEdit and WorldGuard.** + + * **Setup a way to pull a config's hash keys.** These would be used to dynamically get all settings within a hash. diff --git a/prison-core/src/main/java/tech/mcprison/prison/worldguard/PrisonWorldEdit.java b/prison-core/src/main/java/tech/mcprison/prison/worldguard/PrisonWorldEdit.java new file mode 100644 index 000000000..390cb4fa0 --- /dev/null +++ b/prison-core/src/main/java/tech/mcprison/prison/worldguard/PrisonWorldEdit.java @@ -0,0 +1,5 @@ +package tech.mcprison.prison.worldguard; + +public abstract class PrisonWorldEdit { + +} diff --git a/prison-core/src/main/java/tech/mcprison/prison/worldguard/PrisonWorldGuard.java b/prison-core/src/main/java/tech/mcprison/prison/worldguard/PrisonWorldGuard.java new file mode 100644 index 000000000..8757b7419 --- /dev/null +++ b/prison-core/src/main/java/tech/mcprison/prison/worldguard/PrisonWorldGuard.java @@ -0,0 +1,5 @@ +package tech.mcprison.prison.worldguard; + +public abstract class PrisonWorldGuard { + +} diff --git a/prison-spigot/build.gradle b/prison-spigot/build.gradle index 3ab4ae5fe..2043b884a 100644 --- a/prison-spigot/build.gradle +++ b/prison-spigot/build.gradle @@ -94,6 +94,8 @@ dependencies { implementation project(':prison-ranks') implementation project(':prison-sellall') + // implementation project(':prison-worldguard6') + // https://mvnrepository.com/artifact/org.bstats/bstats-base // https://mvnrepository.com/artifact/org.bstats/bstats-bukkit @@ -112,6 +114,28 @@ dependencies { implementation 'org.apache.commons:commons-lang3:3.12.0' + +/* + // https://mvnrepository.com/artifact/com.sk89q.worldedit/worldedit-core + implementation 'com.sk89q.worldedit:worldedit-core:7.2.15' + + // https://mvnrepository.com/artifact/com.sk89q.worldedit/worldedit-bukkit + compileOnly 'com.sk89q.worldedit:worldedit-bukkit:7.2.15' + + + // https://mvnrepository.com/artifact/com.sk89q.worldguard/worldguard-core + compileOnly 'com.sk89q.worldguard:worldguard-core:7.0.8' + + // https://mvnrepository.com/artifact/com.sk89q.worldguard/worldguard-bukkit + compileOnly 'com.sk89q.worldguard:worldguard-bukkit:7.0.8' + + // https://mvnrepository.com/artifact/com.sk89q.worldguard.worldguard-libs/core + implementation 'com.sk89q.worldguard.worldguard-libs:core:7.0.8' +*/ + + + + compileOnly 'me.clip:placeholderapi:2.11.2' //compileOnly 'me.clip:placeholderapi:2.10.9' diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/worldguard/WorldGuardData.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/worldguard/WorldGuardData.java new file mode 100644 index 000000000..e90f54679 --- /dev/null +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/worldguard/WorldGuardData.java @@ -0,0 +1,155 @@ +package tech.mcprison.prison.spigot.worldguard; + +import java.util.ArrayList; +import java.util.List; + +import tech.mcprison.prison.Prison; +import tech.mcprison.prison.internal.platform.Platform; + +public class WorldGuardData { + + private String worldGuardPrefix; + + private boolean enabled; + private String name; + + private String permissionPrefix; + private int priority; + + private boolean denyNonMembers; + private String denyMessage; + + private List flags; + + private int increaseX; + private int increaseZ; + private int increaseY; + + public WorldGuardData( String worldGuardPrefix ) { + super(); + + this.worldGuardPrefix = worldGuardPrefix; + + this.flags = new ArrayList<>(); + + configure(); + } + + private void configure() { + + String wgPrefix = getWorldGuardPrefix(); + + Platform platform = Prison.get().getPlatform(); + + this.enabled = platform.getConfigBooleanFalse( wgPrefix + "enable" ); + + if ( isEnabled() ) { + + this.name = platform.getConfigString( wgPrefix + "name-prefix" ); + + this.permissionPrefix = platform.getConfigString( wgPrefix + "permission-prefix" ); + + this.priority = platform.getConfigInt( wgPrefix + "priority", 10 ); + + this.denyNonMembers = platform.getConfigBooleanFalse( wgPrefix + "deny-non-members" ); + + this.denyMessage = platform.getConfigString( wgPrefix + "deny-message" ); + + List flagKeys = platform.getConfigHashKeys( wgPrefix + "flags" ); + + for (String key : flagKeys) { + boolean includeFlag = platform.getConfigBooleanFalse( wgPrefix + "flags" + "." + key ); + + // Only flags that are enabled are stored: + if ( includeFlag ) { + flags.add( key ); + } + } + + + this.increaseX = platform.getConfigInt( wgPrefix + "increase-x", 0 ); + this.increaseZ = platform.getConfigInt( wgPrefix + "increase-z", 0 ); + this.increaseY = platform.getConfigInt( wgPrefix + "increase-y", 0 ); + + } + + } + + public String getWorldGuardPrefix() { + return worldGuardPrefix; + } + public void setWorldGuardPrefix(String worldGuardPrefix) { + this.worldGuardPrefix = worldGuardPrefix; + } + + public boolean isEnabled() { + return enabled; + } + public void setEnabled(boolean enabled) { + this.enabled = enabled; + } + + public String getName() { + return name; + } + public void setName(String name) { + this.name = name; + } + + public String getPermissionPrefix() { + return permissionPrefix; + } + public void setPermissionPrefix(String permissionPrefix) { + this.permissionPrefix = permissionPrefix; + } + + public int getPriority() { + return priority; + } + public void setPriority(int priority) { + this.priority = priority; + } + + public boolean isDenyNonMembers() { + return denyNonMembers; + } + public void setDenyNonMembers(boolean denyNonMembers) { + this.denyNonMembers = denyNonMembers; + } + + public String getDenyMessage() { + return denyMessage; + } + public void setDenyMessage(String denyMessage) { + this.denyMessage = denyMessage; + } + + public List getFlags() { + return flags; + } + public void setFlags(List flags) { + this.flags = flags; + } + + public int getIncreaseX() { + return increaseX; + } + public void setIncreaseX(int increaseX) { + this.increaseX = increaseX; + } + + public int getIncreaseZ() { + return increaseZ; + } + public void setIncreaseZ(int increaseZ) { + this.increaseZ = increaseZ; + } + + public int getIncreaseY() { + return increaseY; + } + public void setIncreaseY(int increaseY) { + this.increaseY = increaseY; + } + +} diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/worldguard/WorldGuardSettings.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/worldguard/WorldGuardSettings.java new file mode 100644 index 000000000..f9e3b9aa1 --- /dev/null +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/worldguard/WorldGuardSettings.java @@ -0,0 +1,64 @@ +package tech.mcprison.prison.spigot.worldguard; + +import tech.mcprison.prison.file.JsonFileIO; +import tech.mcprison.prison.output.Output; + +public class WorldGuardSettings { + + public static final String WORLD_GUARD_CONFIG_PREFIX = "prison-mines.world-guard."; + public static final String WORLD_GUARD_CONFIG_REGION_MINE = "region-mine"; + public static final String WORLD_GUARD_CONFIG_REGION_MINE_AREA = "region-mine-area"; + + private String wgPrefixRegionMine; + private String wgPrefixRegionMineArea; + + private WorldGuardData mineRegion; + private WorldGuardData mineAreaRegion; + + public WorldGuardSettings() { + super(); + + wgPrefixRegionMine = WORLD_GUARD_CONFIG_PREFIX + WORLD_GUARD_CONFIG_REGION_MINE + "."; + wgPrefixRegionMineArea = WORLD_GUARD_CONFIG_PREFIX + WORLD_GUARD_CONFIG_REGION_MINE_AREA + "."; + + mineRegion = new WorldGuardData( wgPrefixRegionMine ); + mineAreaRegion = new WorldGuardData( wgPrefixRegionMineArea ); + + String json = new JsonFileIO().toString( this ); + + Output.get().logInfo( "WorldGuardSettings: \n" + json ); + } + + + + + public String getWGPrefixRegionMine() { + return wgPrefixRegionMine; + } + public void setWGPrefixRegionMine(String wgPrefixRegionMine) { + this.wgPrefixRegionMine = wgPrefixRegionMine; + } + + public String getWGPrefixRegionMineArea() { + return wgPrefixRegionMineArea; + } + public void setWGPrefixRegionMineArea(String wgPrefixRegionMineArea) { + this.wgPrefixRegionMineArea = wgPrefixRegionMineArea; + } + + public WorldGuardData getMineRegion() { + return mineRegion; + } + public void setMineRegion(WorldGuardData mineRegion) { + this.mineRegion = mineRegion; + } + + public WorldGuardData getMineAreaRegion() { + return mineAreaRegion; + } + public void setMineAreaRegion(WorldGuardData mineAreaRegion) { + this.mineAreaRegion = mineAreaRegion; + } + + +} diff --git a/prison-worldguard6/build.gradle b/prison-worldguard6/build.gradle new file mode 100644 index 000000000..93874db44 --- /dev/null +++ b/prison-worldguard6/build.gradle @@ -0,0 +1,123 @@ +/* + * Prison is a Minecraft plugin for the prison game mode. + * Copyright (C) 2017 The Prison Team + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +group 'tech.mcprison' + +apply plugin: 'java' + +compileJava.options.encoding = 'UTF-8' +compileTestJava.options.encoding = "UTF-8" + +//sourceCompatibility = 1.8 + + +// https://www.spigotmc.org/wiki/spigot-gradle/ + + +repositories { + mavenCentral() + + + maven { + url = 'https://hub.spigotmc.org/nexus/content/repositories/snapshots/' + + // As of Gradle 5.1, you can limit this to only those + // dependencies you expect from it + content { + includeGroup 'org.bukkit' + includeGroup 'org.spigotmc' + } + } + /* + As Spigot-API depends on the BungeeCord ChatComponent-API, + we need to add the Sonatype OSS repository, as Gradle, + in comparison to maven, doesn't want to understand the ~/.m2 + directory unless added using mavenLocal(). Maven usually just gets + it from there, as most people have run the BuildTools at least once. + This is therefore not needed if you're using the full Spigot/CraftBukkit, + or if you're using the Bukkit API. + */ + maven { url = 'https://oss.sonatype.org/content/repositories/snapshots' } + maven { url = 'https://oss.sonatype.org/content/repositories/central' } + + // mavenLocal() // This is needed for CraftBukkit and Spigot. + maven { + url "https://mvnrepository.com/artifact" + } + + maven { url = "https://hub.spigotmc.org/nexus/content/groups/public" } + + maven { url = "https://maven.enginehub.org/repo/" } +} + + + +dependencies { + implementation project(':prison-core') +// implementation project(':prison-mines') +// implementation project(':prison-ranks') +// implementation project(':prison-sellall') + + + // 1.9.4-R0.1-SNAPSHOT has been the version used for a long time: +// compileOnly 'org.spigotmc:spigot-api:1.9.4-R0.1-SNAPSHOT' + // 1.12.2-R0.1-SNAPSHOT works well: +// compileOnly 'org.spigotmc:spigot-api:1.12.2-R0.1-SNAPSHOT' + // 1.13.2 fails since deprecated functions have been removed. + compileOnly 'org.spigotmc:spigot-api:1.13.2-R0.1-SNAPSHOT' + + + + // https://mvnrepository.com/artifact/com.sk89q.worldedit/worldedit-core + implementation 'com.sk89q.worldedit:worldedit-core:6.0.1' + //implementation 'com.sk89q.worldedit:worldedit-core:7.2.15' + + // https://mvnrepository.com/artifact/com.sk89q.worldedit/worldedit-bukkit + compileOnly 'com.sk89q.worldedit:worldedit-bukkit:6.1.5' + //compileOnly 'com.sk89q.worldedit:worldedit-bukkit:7.2.15' + + + // https://mvnrepository.com/artifact/com.sk89q.worldguard/worldguard-legacy + // NOTE: although the following does exist, its unable to be pulled in so instead + // the jar is included. + //compileOnly 'com.sk89q.worldguard:worldguard-legacy:6.1.2' + + + // https://mvnrepository.com/artifact/com.sk89q.worldguard/worldguard-core + //compileOnly 'com.sk89q.worldguard:worldguard-core:7.0.8' + + // https://mvnrepository.com/artifact/com.sk89q.worldguard/worldguard-bukkit + //compileOnly 'com.sk89q.worldguard:worldguard-bukkit:7.0.8' + + // https://mvnrepository.com/artifact/com.sk89q.worldguard.worldguard-libs/core + //implementation 'com.sk89q.worldguard.worldguard-libs:core:7.0.8' + + + + + compileOnly fileTree(dir: 'lib', include: ['*.jar'] ); + + + + + testImplementation group: 'junit', name: 'junit', version: '4.12' + +} + + + diff --git a/prison-worldguard6/src/main/java/tech/mcprison/worldguard6/worldguard/PrisonWorldEdit6.java b/prison-worldguard6/src/main/java/tech/mcprison/worldguard6/worldguard/PrisonWorldEdit6.java new file mode 100644 index 000000000..d5f1345d4 --- /dev/null +++ b/prison-worldguard6/src/main/java/tech/mcprison/worldguard6/worldguard/PrisonWorldEdit6.java @@ -0,0 +1,28 @@ +package tech.mcprison.worldguard6.worldguard; + +import tech.mcprison.prison.worldguard.PrisonWorldEdit; + +public class PrisonWorldEdit6 + extends PrisonWorldEdit +{ + + public PrisonWorldEdit6() { + super(); + + } + + public void getWorldEditActor( org.bukkit.entity.Player bukkitPlayer ) { + +// Player results = BukkitAdapter.; + +// Bukkit + + + +// com.sk89q.worldedit.bukkit.BukkitPlayer; +// BukkitAdapter.; + +// return results; + } + +} diff --git a/prison-worldguard6/src/main/java/tech/mcprison/worldguard6/worldguard/PrisonWorldGuard6.java b/prison-worldguard6/src/main/java/tech/mcprison/worldguard6/worldguard/PrisonWorldGuard6.java new file mode 100644 index 000000000..e747056e3 --- /dev/null +++ b/prison-worldguard6/src/main/java/tech/mcprison/worldguard6/worldguard/PrisonWorldGuard6.java @@ -0,0 +1,14 @@ +package tech.mcprison.worldguard6.worldguard; + +import tech.mcprison.prison.worldguard.PrisonWorldGuard; + +public class PrisonWorldGuard6 + extends PrisonWorldGuard +{ + + public PrisonWorldGuard6() { + super(); + + } + +} diff --git a/prison-worldguard7/build.gradle b/prison-worldguard7/build.gradle new file mode 100644 index 000000000..96a5b5e1d --- /dev/null +++ b/prison-worldguard7/build.gradle @@ -0,0 +1,85 @@ +/* + * Prison is a Minecraft plugin for the prison game mode. + * Copyright (C) 2017 The Prison Team + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +group 'tech.mcprison' + +apply plugin: 'java' + +compileJava.options.encoding = 'UTF-8' +compileTestJava.options.encoding = "UTF-8" + +//sourceCompatibility = 1.8 + +repositories { + mavenCentral() + +} + + + +dependencies { + implementation project(':prison-core') +// implementation project(':prison-mines') +// implementation project(':prison-ranks') +// implementation project(':prison-sellall') + + + + // https://mvnrepository.com/artifact/com.sk89q.worldedit/worldedit-core + implementation 'com.sk89q.worldedit:worldedit-core:6.0.1' + //implementation 'com.sk89q.worldedit:worldedit-core:7.2.15' + + // https://mvnrepository.com/artifact/com.sk89q.worldedit/worldedit-bukkit + compileOnly 'com.sk89q.worldedit:worldedit-bukkit:6.1.4' + //compileOnly 'com.sk89q.worldedit:worldedit-bukkit:7.2.15' + + + // https://mvnrepository.com/artifact/com.sk89q.worldguard/worldguard-legacy + compileOnly 'com.sk89q.worldguard:worldguard-legacy:6.1.2' + + + // https://mvnrepository.com/artifact/com.sk89q.worldguard/worldguard-core + //compileOnly 'com.sk89q.worldguard:worldguard-core:7.0.8' + + // https://mvnrepository.com/artifact/com.sk89q.worldguard/worldguard-bukkit + //compileOnly 'com.sk89q.worldguard:worldguard-bukkit:7.0.8' + + // https://mvnrepository.com/artifact/com.sk89q.worldguard.worldguard-libs/core + //implementation 'com.sk89q.worldguard.worldguard-libs:core:7.0.8' + + + + + // 1.9.4-R0.1-SNAPSHOT has been the version used for a long time: +// compileOnly 'org.spigotmc:spigot-api:1.9.4-R0.1-SNAPSHOT' + // 1.12.2-R0.1-SNAPSHOT works well: +// compileOnly 'org.spigotmc:spigot-api:1.12.2-R0.1-SNAPSHOT' + // 1.13.2 fails since deprecated functions have been removed. + //compileOnly 'org.spigotmc:spigot-api:1.13.2-R0.1-SNAPSHOT' + + + + + + + testImplementation group: 'junit', name: 'junit', version: '4.12' + +} + + + From b1f179839a29f3ef66fb58e6059feed19762b75f Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Mon, 10 Jul 2023 20:02:54 -0400 Subject: [PATCH 006/151] Bug fix... this is a continuation of a prior issue of prison commands not being mapped to their assigned command name by bukkit when prison's command handler registers them. This was an issue with another plugin that registered `/gui` before prison was able to, so then all of prison's gui commands were mapped to `/prison:gui`. So where this was an issue was with `/prestige` trying to run the gui presetige confirmation which was trying to kick off a GuiPlus command as a result of this improper mis-match. Tested to confirm it is now functional. Changed all occurrences that I could find that also needed to be mapped. --- docs/changelog_v3.3.x.md | 5 + .../prison/spigot/SpigotScheduler.java | 8 +- .../spigot/backpacks/BackpacksListeners.java | 8 +- .../PrisonSpigotPrestigeCommands.java | 6 +- .../spigot/gui/ListenersPrisonManager.java | 94 +++++++++++++------ .../prison/spigot/gui/SpigotGUIMenuTools.java | 7 +- 6 files changed, 92 insertions(+), 36 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index fcb92d60f..8ecda1c0c 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -17,6 +17,11 @@ These change logs represent the work that has been going on within prison. # 3.3.0-alpha.15 2023-07-10 +* **Bug fix... this is a continuation of a prior issue of prison commands not being mapped to their assigned command name by bukkit when prison's command handler registers them.** +This was an issue with another plugin that registered `/gui` before prison was able to, so then all of prison's gui commands were mapped to `/prison:gui`. So where this was an issue was with `/prestige` trying to run the gui presetige confirmation which was trying to kick off a GuiPlus command as a result of this improper mis-match. +Tested to confirm it is now functional. Changed all occurrences that I could find that also needed to be mapped. + + * **Start to setup support for WorldEdit and WorldGuard.** diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/SpigotScheduler.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/SpigotScheduler.java index f290b4cc4..eb992ebd6 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/SpigotScheduler.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/SpigotScheduler.java @@ -65,7 +65,9 @@ public void dispatchCommand(Player player, String command) { if ( player != null && player instanceof SpigotPlayer ) { SpigotPlayer sPlayer = (SpigotPlayer) player; - Bukkit.dispatchCommand( sPlayer.getWrapper(), command ); + sPlayer.dispatchCommand( command ); + +// Bukkit.dispatchCommand( sPlayer.getWrapper(), command ); } } @@ -80,7 +82,9 @@ public void performCommand(Player player, String command) { SpigotPlayer sPlayer = (SpigotPlayer) p; - sPlayer.getWrapper().performCommand( command ); + sPlayer.dispatchCommand( command ); + +// sPlayer.getWrapper().performCommand( command ); } } } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/backpacks/BackpacksListeners.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/backpacks/BackpacksListeners.java index 880241c65..74c95c85d 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/backpacks/BackpacksListeners.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/backpacks/BackpacksListeners.java @@ -11,6 +11,8 @@ import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.inventory.ItemStack; + +import tech.mcprison.prison.Prison; import tech.mcprison.prison.spigot.SpigotPrison; import tech.mcprison.prison.spigot.SpigotUtil; import tech.mcprison.prison.spigot.compat.Compatibility; @@ -130,9 +132,11 @@ private void backpackItemClickAction(PlayerInteractEvent e) { if (materialConf != null && inHandItem != null && inHandItem.getType() == materialConf.getType() && inHandItem.hasItemMeta() && inHandItem.getItemMeta().hasDisplayName() && inHandItem.getItemMeta().getDisplayName().equalsIgnoreCase(SpigotPrison.format(BackpacksUtil.get().getBackpacksConfig().getString("Options.BackPack_Item_Title")))) { if (getBoolean(BackpacksUtil.get().getBackpacksConfig().getString("Options.Multiple-BackPacks-For-Player-Enabled"))){ - Bukkit.dispatchCommand(p, "gui backpackslist"); + Bukkit.dispatchCommand(p, + Prison.get().getCommandHandler().findRegisteredCommand( "gui backpackslist" )); } else { - Bukkit.dispatchCommand(p, "gui backpack"); + Bukkit.dispatchCommand(p, + Prison.get().getCommandHandler().findRegisteredCommand( "gui backpack" )); } e.setCancelled(true); } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/commands/PrisonSpigotPrestigeCommands.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/commands/PrisonSpigotPrestigeCommands.java index da434a465..688191607 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/commands/PrisonSpigotPrestigeCommands.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/commands/PrisonSpigotPrestigeCommands.java @@ -116,7 +116,8 @@ public void prisonManagerPrestige(CommandSender sender, // } // // if ( PrisonRanks.getInstance().getLadderManager().getLadder("prestiges") == null ) { -// Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "ranks ladder create prestiges"); +// Bukkit.dispatchCommand(Bukkit.getConsoleSender(), +// Prison.get().getCommandHandler().findRegisteredCommand( "ranks ladder create prestiges" )); // } // // PrisonRanks rankPlugin; @@ -166,7 +167,8 @@ public void prisonManagerPrestige(CommandSender sender, // } // else { // // Bypassing prestige confirmations: -// Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "rankup prestiges"); +// Bukkit.dispatchCommand(Bukkit.getConsoleSender(), +// Prison.get().getCommandHandler().findRegisteredCommand( "rankup prestiges" )); // } // } // } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/ListenersPrisonManager.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/ListenersPrisonManager.java index ba981046d..cfe91068e 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/ListenersPrisonManager.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/ListenersPrisonManager.java @@ -700,9 +700,11 @@ else if ( SpigotGUIMenuTools.getInstance().processGUIPage( p, title, e ) ) { if (parts[0].equalsIgnoreCase("Backpack")){ if (e.isRightClick() && e.isShiftClick()){ if (parts[2].equalsIgnoreCase("default")){ - Bukkit.dispatchCommand(p, "backpack delete " + parts[1]); + Bukkit.dispatchCommand(p, + Prison.get().getCommandHandler().findRegisteredCommand( "backpack delete " + parts[1] )); } else { - Bukkit.dispatchCommand(p, "backpack delete " + parts[1] + " " + parts[2]); + Bukkit.dispatchCommand(p, + Prison.get().getCommandHandler().findRegisteredCommand( "backpack delete " + parts[1] + " " + parts[2] )); } p.closeInventory(); BackpacksAdminListGUI gui = new BackpacksAdminListGUI(p, parts[1]); @@ -766,7 +768,8 @@ else if ( SpigotGUIMenuTools.getInstance().processGUIPage( p, title, e ) ) { // } // // if ( isPageAction && command != null ) { -// Bukkit.dispatchCommand(p, command); +// Bukkit.dispatchCommand(p, +// Prison.get().getCommandHandler().findRegisteredCommand( command )); // // } // } @@ -833,7 +836,8 @@ private void backpacksList(Player p, String buttonNameMain, String[] parts) { } String finalID = String.valueOf(freeID); - Bukkit.dispatchCommand(p, "gui backpack " + finalID); + Bukkit.dispatchCommand(p, + Prison.get().getCommandHandler().findRegisteredCommand( "gui backpack " + finalID )); } } else if (buttonNameMain.equalsIgnoreCase("Backpack")){ @@ -1321,7 +1325,8 @@ private boolean guiConditions(InventoryClickEvent e, Player p) { private void prisonSetupConfirmGUI(InventoryClickEvent e, Player p, String[] parts) { if (parts[0].equalsIgnoreCase("Confirm:")){ - Bukkit.dispatchCommand(p, "ranks autoConfigure"); + Bukkit.dispatchCommand(p, + Prison.get().getCommandHandler().findRegisteredCommand( "ranks autoConfigure" )); } else if (parts[0].equalsIgnoreCase("Cancel:")){ Output.get().sendInfo(new SpigotPlayer(p), messages.getString(MessagesConfig.StringID.spigot_message_event_cancelled)); } @@ -1406,7 +1411,9 @@ private void mineBlockPercentage(InventoryClickEvent e, Player p, String[] parts // Execute the command if (part4 != null) { - Bukkit.dispatchCommand(p, "mines block set " + part2 + " " + part3 + " " + part4); + Bukkit.dispatchCommand(p, + Prison.get().getCommandHandler().findRegisteredCommand( + "mines block set " + part2 + " " + part3 + " " + part4 )); } // Cancel the event @@ -1524,7 +1531,9 @@ private void sellAllItemValue(InventoryClickEvent e, Player p, String[] parts) { if (e.isLeftClick()){ // Execute the command - Bukkit.dispatchCommand(p,"sellall edit " + part2 + " " + part3); + Bukkit.dispatchCommand(p, + Prison.get().getCommandHandler().findRegisteredCommand( + "sellall edit " + part2 + " " + part3 )); // Close the inventory p.closeInventory(); @@ -1731,7 +1740,8 @@ private void laddersGUI(InventoryClickEvent e, Player p, String buttonNameMain, else { // Execute the command - Bukkit.dispatchCommand(p, "ranks ladder delete " + buttonNameMain); + Bukkit.dispatchCommand(p, + Prison.get().getCommandHandler().findRegisteredCommand( "ranks ladder delete " + buttonNameMain )); e.setCancelled(true); p.closeInventory(); SpigotLaddersGUI gui = new SpigotLaddersGUI(p, 1, "gui ladders", "gui" ); @@ -1776,7 +1786,8 @@ private void ranksGUI(InventoryClickEvent e, Player p, String buttonNameMain, St RankLadder rLadder = rank.getLadder(); // Execute the command. - Bukkit.dispatchCommand(p, "ranks delete " + buttonNameMain); + Bukkit.dispatchCommand(p, + Prison.get().getCommandHandler().findRegisteredCommand( "ranks delete " + buttonNameMain )); e.setCancelled(true); p.closeInventory(); SpigotRanksGUI gui = new SpigotRanksGUI( p, rLadder, 1, "gui admin ranks", "gui" ); @@ -1802,7 +1813,8 @@ private void playerPrestigesGUI(InventoryClickEvent e, Player p, String buttonNa // Close the inventory. p.closeInventory(); // Execute the command. - Bukkit.dispatchCommand(p, "prestige"); + Bukkit.dispatchCommand(p, + Prison.get().getCommandHandler().findRegisteredCommand( "prestige" )); } // Cancel the event. @@ -1931,7 +1943,9 @@ private void playerRanksGUI(InventoryClickEvent e, Player p, String buttonNameMa // Check the buttonName and do the actions. String message = Text.stripColor( messages.getString(MessagesConfig.StringID.spigot_gui_lore_rankup) ); if (buttonNameMain.equals(SpigotPrison.format( message ))){ - Bukkit.dispatchCommand(p, "rankup " + guiConfig.getString("Options.Ranks.Ladder")); + Bukkit.dispatchCommand(p, + Prison.get().getCommandHandler().findRegisteredCommand( + "rankup " + guiConfig.getString("Options.Ranks.Ladder" ))); p.closeInventory(); } @@ -1945,7 +1959,8 @@ private void rankUPCommandsGUI(InventoryClickEvent e, Player p, String buttonNam if (e.isShiftClick() && e.isRightClick()) { // Execute the command. - Bukkit.dispatchCommand(p, "ranks command remove " + buttonNameMain); + Bukkit.dispatchCommand(p, + Prison.get().getCommandHandler().findRegisteredCommand( "ranks command remove " + buttonNameMain )); // Cancel the event. e.setCancelled(true); // Close the inventory. @@ -1980,7 +1995,8 @@ private void rankPriceGUI(InventoryClickEvent e, Player p, String[] parts) { if (e.isLeftClick()){ // Execute the command. - Bukkit.dispatchCommand(p,"ranks set cost " + part2 + " " + part3); + Bukkit.dispatchCommand(p, + Prison.get().getCommandHandler().findRegisteredCommand( "ranks set cost " + part2 + " " + part3 )); // Close the inventory. p.closeInventory(); @@ -2080,7 +2096,8 @@ private void minesGUI(InventoryClickEvent e, Player p, String buttonNameMain, St // Check the clicks. if (e.isShiftClick() && e.isRightClick()) { // Execute the command. - Bukkit.dispatchCommand(p, "mines delete " + buttonNameMain); + Bukkit.dispatchCommand(p, + Prison.get().getCommandHandler().findRegisteredCommand( "mines delete " + buttonNameMain )); // Cancel the event. e.setCancelled(true); // Close the inventory. @@ -2125,10 +2142,14 @@ private void playerMinesGUI(Player p, InventoryClickEvent e) { if (errorHasMiningPermission && (p.hasPermission(permission + mineName) || p.hasPermission(permission.substring(0, permission.length() - 1)))){ - Bukkit.dispatchCommand(p, SpigotPrison.format(guiConfig.getString("Options.Mines.CommandWarpPlugin") + " " + mineName)); + Bukkit.dispatchCommand(p, + Prison.get().getCommandHandler().findRegisteredCommand( + SpigotPrison.format(guiConfig.getString("Options.Mines.CommandWarpPlugin") + " " + mineName ))); } else if (hasMiningPermission || p.hasPermission(permission + mineName) || p.hasPermission(permission.substring(0, permission.length() - 1))){ - Bukkit.dispatchCommand(p, SpigotPrison.format(guiConfig.getString("Options.Mines.CommandWarpPlugin") + " " + mineName)); + Bukkit.dispatchCommand(p, + Prison.get().getCommandHandler().findRegisteredCommand( + SpigotPrison.format(guiConfig.getString("Options.Mines.CommandWarpPlugin") + " " + mineName ))); } } } @@ -2155,13 +2176,16 @@ private void mineInfoGUI(InventoryClickEvent e, Player p, String[] parts) { // Check the clickType and do the actions. if (e.isLeftClick()) { // Execute the command. - Bukkit.dispatchCommand(p, "mines reset " + mineName); + Bukkit.dispatchCommand(p, + Prison.get().getCommandHandler().findRegisteredCommand( "mines reset " + mineName )); } else if (e.isRightClick()){ // Execute the command. - Bukkit.dispatchCommand(p, "mines set skipReset " + mineName); + Bukkit.dispatchCommand(p, + Prison.get().getCommandHandler().findRegisteredCommand( "mines set skipReset " + mineName )); } else if (e.isRightClick() && e.isShiftClick()){ // Execute the command. - Bukkit.dispatchCommand(p, "mines set zeroBlockResetDelay " + mineName); + Bukkit.dispatchCommand(p, + Prison.get().getCommandHandler().findRegisteredCommand( "mines set zeroBlockResetDelay " + mineName )); } // Cancel the event. @@ -2173,7 +2197,8 @@ private void mineInfoGUI(InventoryClickEvent e, Player p, String[] parts) { case "Mine_Spawn:": // Execute the command. - Bukkit.dispatchCommand(p, "mines set spawn " + mineName); + Bukkit.dispatchCommand(p, + Prison.get().getCommandHandler().findRegisteredCommand( "mines set spawn " + mineName )); // Cancel the event. e.setCancelled(true); @@ -2195,7 +2220,8 @@ private void mineInfoGUI(InventoryClickEvent e, Player p, String[] parts) { p.closeInventory(); // Execute the Command. - Bukkit.dispatchCommand(p, "mines tp " + mineName); + Bukkit.dispatchCommand(p, + Prison.get().getCommandHandler().findRegisteredCommand( "mines tp " + mineName )); break; @@ -2245,7 +2271,8 @@ private void minesDeleteGUI(Player p, String[] parts) { if (buttonname.equals("Confirm:")) { // Confirm - Bukkit.dispatchCommand(p, "mines delete " + mineName + " confirm"); + Bukkit.dispatchCommand(p, + Prison.get().getCommandHandler().findRegisteredCommand( "mines delete " + mineName + " confirm" )); // Close the Inventory p.closeInventory(); @@ -2254,7 +2281,8 @@ private void minesDeleteGUI(Player p, String[] parts) { } else if (buttonname.equals("Cancel:")) { // Cancel - Bukkit.dispatchCommand(p, "mines delete " + mineName + " cancel"); + Bukkit.dispatchCommand(p, + Prison.get().getCommandHandler().findRegisteredCommand( "mines delete " + mineName + " cancel" )); // Close the inventory p.closeInventory(); @@ -2281,7 +2309,9 @@ private void blocksGUI(InventoryClickEvent e, Player p, String[] parts) { if (e.isShiftClick() && e.isRightClick()) { // Execute the command - Bukkit.dispatchCommand(p, "mines block remove " + mineName + " " + buttonname); + Bukkit.dispatchCommand(p, + Prison.get().getCommandHandler().findRegisteredCommand( + "mines block remove " + mineName + " " + buttonname )); // Cancel the event e.setCancelled(true); @@ -2330,7 +2360,9 @@ private void resetTimeGUI(InventoryClickEvent e, Player p, String[] parts) { if (e.isLeftClick()){ // Execute the command - Bukkit.dispatchCommand(p,"mines set resettime " + part2 + " " + part3); + Bukkit.dispatchCommand(p, + Prison.get().getCommandHandler().findRegisteredCommand( + "mines set resettime " + part2 + " " + part3 )); // Cancel the event e.setCancelled(true); @@ -2445,7 +2477,9 @@ private void mineNotificationsGUI(InventoryClickEvent e, Player p, String[] part typeNotification = "within"; // Execute command - Bukkit.dispatchCommand(p, "mines set notification " + mineName + " " + typeNotification + " 0"); + Bukkit.dispatchCommand(p, + Prison.get().getCommandHandler().findRegisteredCommand( + "mines set notification " + mineName + " " + typeNotification + " 0" )); // Cancel the event and close the inventory e.setCancelled(true); @@ -2471,7 +2505,9 @@ private void mineNotificationsGUI(InventoryClickEvent e, Player p, String[] part typeNotification = "disabled"; // Execute the command - Bukkit.dispatchCommand(p, "mines set notification " + mineName + " " + typeNotification + " 0"); + Bukkit.dispatchCommand(p, + Prison.get().getCommandHandler().findRegisteredCommand( + "mines set notification " + mineName + " " + typeNotification + " 0" )); // Cancel the event and close the inventory e.setCancelled(true); @@ -2512,7 +2548,9 @@ private void radiusGUI(InventoryClickEvent e, Player p, String[] parts) { if (e.isLeftClick()){ // Execute the command - Bukkit.dispatchCommand(p,"mines set notification " + part2 + " " + typeNotification + " " + part3); + Bukkit.dispatchCommand(p, + Prison.get().getCommandHandler().findRegisteredCommand( + "mines set notification " + part2 + " " + typeNotification + " " + part3 )); // Cancel the event e.setCancelled(true); diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/SpigotGUIMenuTools.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/SpigotGUIMenuTools.java index 195fb4b9b..c47c52a46 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/SpigotGUIMenuTools.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/SpigotGUIMenuTools.java @@ -11,6 +11,7 @@ import com.cryptomorin.xseries.XMaterial; +import tech.mcprison.prison.Prison; import tech.mcprison.prison.spigot.gui.guiutility.Button; import tech.mcprison.prison.spigot.gui.guiutility.ButtonLore; import tech.mcprison.prison.spigot.gui.guiutility.PrisonGUI; @@ -356,7 +357,8 @@ public boolean processGUIPage( Player p, String title, InventoryClickEvent e ) { if ( command != null ) { isPageAction = true; - Bukkit.dispatchCommand(p, command); + Bukkit.dispatchCommand(p, + Prison.get().getCommandHandler().findRegisteredCommand( command )); } } @@ -390,7 +392,8 @@ else if ( currentItem != null && currentItem.hasItemMeta() ) { if ( isMenuToolsPage && command != null ) { isPageAction = true; - Bukkit.dispatchCommand(p, command); + Bukkit.dispatchCommand(p, + Prison.get().getCommandHandler().findRegisteredCommand( command )); } } From 9d5afc7f75a2ca572355813dec50d1f4c0425d03 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Tue, 11 Jul 2023 22:33:56 -0400 Subject: [PATCH 007/151] Sellall : remove the disabled worlds setting in the configs since it is obsolete and never used. The correct way to disable prison in specific worlds is by using the config.yml settings for prisonCommandHandler.exclude-worlds. --- docs/changelog_v3.3.x.md | 6 ++- .../prison/spigot/sellall/SellAllUtil.java | 50 ++++++++++--------- 2 files changed, 32 insertions(+), 24 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 8ecda1c0c..bad776e52 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -14,7 +14,11 @@ These change logs represent the work that has been going on within prison. -# 3.3.0-alpha.15 2023-07-10 +# 3.3.0-alpha.15 2023-07-11 + + +* **Sellall : remove the disabled worlds setting in the configs since it is obsolete and never used.** +The correct way to disable prison in specific worlds is by using the config.yml settings for prisonCommandHandler.exclude-worlds. * **Bug fix... this is a continuation of a prior issue of prison commands not being mapped to their assigned command name by bukkit when prison's command handler registers them.** diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/sellall/SellAllUtil.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/sellall/SellAllUtil.java index ec41604a3..edc4b85d4 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/sellall/SellAllUtil.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/sellall/SellAllUtil.java @@ -69,7 +69,7 @@ public class SellAllUtil private ArrayList sellAllItemTriggers; private ArrayList activePlayerDelay = new ArrayList<>(); - private List sellAllDisabledWorlds; +// private List sellAllDisabledWorlds; // private MessagesConfig messages; private double defaultMultiplier; private int defaultSellAllDelay; @@ -674,16 +674,20 @@ public boolean checkIfPlayerAutosellIsActive(Player p) { return results; } - /** - * Check if Player is in a disabled world, where he can't use sellall sell. - * - * Return True if he's in a disabled world, False if not. - * - * @return boolean. - * */ - public boolean isPlayerInDisabledWorld(Player p){ - return sellAllDisabledWorlds.contains(p.getWorld().getName()); - } +// /** +// * WARNING: Obsolete because disabled worlds are set in config.yml and +// * the command handler shuts down in those worlds. So it will +// * never run any sellall commands in a diabled world. +// * +// * Check if Player is in a disabled world, where he can't use sellall sell. +// * +// * Return True if he's in a disabled world, False if not. +// * +// * @return boolean. +// * */ +// public boolean isPlayerInDisabledWorld(Player p){ +// return sellAllDisabledWorlds.contains(p.getWorld().getName()); +// } /** * Check if Player is waiting for the end of SellAll Sell Delay. @@ -753,7 +757,7 @@ private void initCachedData() { sellAllBlocks = initSellAllBlocks(); sellAllPrestigeMultipliers = initPrestigeMultipliers(); sellAllItemTriggers = initSellAllItemTrigger(); - sellAllDisabledWorlds = initSellAllDisabledWorlds(); +// sellAllDisabledWorlds = initSellAllDisabledWorlds(); defaultMultiplier = Double.parseDouble(sellAllConfig.getString("Options.Multiplier_Default")); defaultSellAllDelay = Integer.parseInt(sellAllConfig.getString("Options.Sell_Delay_Seconds")); defaultAutoSellEarningNotificationDelay = Integer.parseInt(sellAllConfig.getString("Options.Full_Inv_AutoSell_EarnedMoneyNotificationDelay_Delay_Seconds")); @@ -898,13 +902,13 @@ public ArrayList initSellAllItemTrigger(){ return xMaterials; } - /** - * Get List of names of disabled worlds. - * If a Player is in one of these worlds, he won't be able to use SellAll. - * */ - public List initSellAllDisabledWorlds(){ - return sellAllConfig.getStringList("Options.DisabledWorlds"); - } +// /** +// * Get List of names of disabled worlds. +// * If a Player is in one of these worlds, he won't be able to use SellAll. +// * */ +// public List initSellAllDisabledWorlds(){ +// return sellAllConfig.getStringList("Options.DisabledWorlds"); +// } /** * Add a block to SellAll config. @@ -1161,7 +1165,7 @@ private HashMap addInventoryToHashMap(HashMap Date: Wed, 12 Jul 2023 12:06:07 -0400 Subject: [PATCH 008/151] Sellall : remove the disabled worlds setting in the configs since it is obsolete and never used. The correct way to disable prison in specific worlds is by using the config.yml settings for prisonCommandHandler.exclude-worlds. --- .../spigot/commands/PrisonSpigotSellAllCommands.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/commands/PrisonSpigotSellAllCommands.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/commands/PrisonSpigotSellAllCommands.java index 4345aeb55..45ac395d3 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/commands/PrisonSpigotSellAllCommands.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/commands/PrisonSpigotSellAllCommands.java @@ -297,7 +297,7 @@ else if (p == null){ return; } - if (sellAllUtil.isPlayerInDisabledWorld(p)) return; +// if (sellAllUtil.isPlayerInDisabledWorld(p)) return; if (sellAllUtil.isSellAllSellPermissionEnabled){ String permission = sellAllUtil.permissionSellAllSell; @@ -339,7 +339,7 @@ public void sellAllSellHandCommand(CommandSender sender){ return; } - if (sellAllUtil.isPlayerInDisabledWorld(p)) return; +// if (sellAllUtil.isPlayerInDisabledWorld(p)) return; if (sellAllUtil.isSellAllSellPermissionEnabled){ String permission = sellAllUtil.permissionSellAllSell; @@ -373,7 +373,7 @@ public void sellAllSell(Player p){ return; } - if (sellAllUtil.isPlayerInDisabledWorld(p)) return; +// if (sellAllUtil.isPlayerInDisabledWorld(p)) return; if (sellAllUtil.isSellAllSellPermissionEnabled){ String permission = sellAllUtil.permissionSellAllSell; @@ -413,7 +413,7 @@ public void sellAllSellWithDelayCommand(CommandSender sender){ return; } - if (sellAllUtil.isPlayerInDisabledWorld(p)) return; +// if (sellAllUtil.isPlayerInDisabledWorld(p)) return; if (sellAllUtil.isSellAllSellPermissionEnabled){ String permission = sellAllUtil.permissionSellAllSell; @@ -454,7 +454,7 @@ private void sellAllAutoEnableUser(CommandSender sender){ return; } - if (sellAllUtil.isPlayerInDisabledWorld(p)) return; +// if (sellAllUtil.isPlayerInDisabledWorld(p)) return; if (!sellAllUtil.isAutoSellPerUserToggleable){ return; From a5caccd8e2ecf295fb6e895de63ef1e28dad519a Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Wed, 12 Jul 2023 12:10:38 -0400 Subject: [PATCH 009/151] Add new salePrice and purchasePrice to the prison Block. --- docs/changelog_v3.3.x.md | 5 +- .../mcprison/prison/internal/block/Block.java | 37 ++++++++++++++ .../prison/internal/block/PrisonBlock.java | 50 +++++++++++++++++++ 3 files changed, 91 insertions(+), 1 deletion(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index bad776e52..a7cdb968b 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -14,7 +14,10 @@ These change logs represent the work that has been going on within prison. -# 3.3.0-alpha.15 2023-07-11 +# 3.3.0-alpha.15 2023-07-12 + + +* **Add new salePrice and purchasePrice to the prison Block.** * **Sellall : remove the disabled worlds setting in the configs since it is obsolete and never used.** diff --git a/prison-core/src/main/java/tech/mcprison/prison/internal/block/Block.java b/prison-core/src/main/java/tech/mcprison/prison/internal/block/Block.java index 5e166a0cf..df65f516f 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/internal/block/Block.java +++ b/prison-core/src/main/java/tech/mcprison/prison/internal/block/Block.java @@ -121,4 +121,41 @@ default boolean isEmpty() { public void setBlockName( String blockName ); + /** + *

The sale price is the amount that is paid to the player when they + * sell their items. A null indicates that no price was set. + *

+ * + * @return + */ + public Double getSalePrice(); + + /** + *

The sale price is the amount that is paid to the player when they + * sell their items. A null indicates that no price was set. + *

+ * + * @param price + */ + public void setSalePrice( Double price ); + + /** + *

The purchase price is what player pays to purchase the items. + * A null indicates that no price was set. + *

+ * + * @return + */ + public Double getPurchasePrice(); + + /** + *

The purchase price is what player pays to purchase the items., + * A null indicates that no price was set. + *

+ * + * @param price + */ + public void setPurchasePrice( Double price ); + + } diff --git a/prison-core/src/main/java/tech/mcprison/prison/internal/block/PrisonBlock.java b/prison-core/src/main/java/tech/mcprison/prison/internal/block/PrisonBlock.java index 70215ca7b..2f997747a 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/internal/block/PrisonBlock.java +++ b/prison-core/src/main/java/tech/mcprison/prison/internal/block/PrisonBlock.java @@ -43,6 +43,10 @@ public class PrisonBlock private Location location = null; + private Double salePrice = null; + private Double purchasePrice = null; + + static { AIR = new PrisonBlock( InternalBlockTypes.AIR.name(), false ); GLASS = new PrisonBlock( InternalBlockTypes.GLASS.name(), true ); @@ -285,6 +289,52 @@ public void setLocation( Location location ) { this.location = location; } + + /** + *

The sale price is the amount that is paid to the player when they + * sell their items. A null indicates that no price was set. + *

+ * + * @return + */ + public Double getSalePrice() { + return salePrice; + } + + /** + *

The sale price is the amount that is paid to the player when they + * sell their items. A null indicates that no price was set. + *

+ * + * @param price + */ + public void setSalePrice( Double price ) { + this.salePrice = price; + } + + /** + *

The purchase price is what player pays to purchase the items. + * A null indicates that no price was set. + *

+ * + * @return + */ + public Double getPurchasePrice() { + return purchasePrice; + } + + /** + *

The purchase price is what player pays to purchase the items., + * A null indicates that no price was set. + *

+ * + * @param price + */ + public void setPurchasePrice( Double price ) { + this.purchasePrice = price; + } + + public PrisonBlock clone() { return new PrisonBlock( this ); } From 29190d25334c6e88589c214372ce9c09d2262079 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Wed, 12 Jul 2023 12:12:37 -0400 Subject: [PATCH 010/151] Allow additional parameters to be passed on the gradlew.bat command; needed for additional debugging and etc... --- docs/changelog_v3.3.x.md | 3 +++ gradlew8.bat | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index a7cdb968b..981f5cfa9 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -17,6 +17,9 @@ These change logs represent the work that has been going on within prison. # 3.3.0-alpha.15 2023-07-12 +* **Allow additional parameters to be passed on the gradlew.bat command; needed for additional debugging and etc...** + + * **Add new salePrice and purchasePrice to the prison Block.** diff --git a/gradlew8.bat b/gradlew8.bat index 009240f46..7230d4d90 100644 --- a/gradlew8.bat +++ b/gradlew8.bat @@ -1 +1 @@ -./gradlew build -Dorg.gradle.java.home="C:\Program Files\Java\jdk1.8.0_321" --stacktrace \ No newline at end of file +./gradlew build -Dorg.gradle.java.home="C:\Program Files\Java\jdk1.8.0_321" --stacktrace %* \ No newline at end of file From 91e573ddb3febf6b7873503dc4e666ccbc5ea1dc Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Thu, 13 Jul 2023 00:04:32 -0400 Subject: [PATCH 011/151] Updated Prison's PlayerInventory to include 'contents' and 'extraContents' to match the bukkit PlayerInventory object. Within the SpigotPlayerInventory class, overrode the behavior of removeItem to ensure that obscure inventory locations are being removed, since there was a bug where you can get all inventory items, then remove them, and they would not remove all occurrences of the items stacks that were initially returned, such as when someone is wearing an item as a hat, or holding something in one of their hands. --- docs/changelog_v3.3.x.md | 6 +- .../internal/inventory/PlayerInventory.java | 8 + .../prison/spigot/game/SpigotPlayer.java | 5 +- .../inventory/SpigotPlayerInventory.java | 156 +++++++++++++++++- 4 files changed, 167 insertions(+), 8 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 981f5cfa9..cb0f718bf 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -14,7 +14,11 @@ These change logs represent the work that has been going on within prison. -# 3.3.0-alpha.15 2023-07-12 +# 3.3.0-alpha.15 2023-07-13 + + +* **Updated Prison's PlayerInventory to include 'contents' and 'extraContents' to match the bukkit PlayerInventory object.** +Within the SpigotPlayerInventory class, overrode the behavior of removeItem to ensure that obscure inventory locations are being removed, since there was a bug where you can get all inventory items, then remove them, and they would not remove all occurrences of the items stacks that were initially returned, such as when someone is wearing an item as a hat, or holding something in one of their hands. * **Allow additional parameters to be passed on the gradlew.bat command; needed for additional debugging and etc...** diff --git a/prison-core/src/main/java/tech/mcprison/prison/internal/inventory/PlayerInventory.java b/prison-core/src/main/java/tech/mcprison/prison/internal/inventory/PlayerInventory.java index 723b4b11d..b8d4ab439 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/internal/inventory/PlayerInventory.java +++ b/prison-core/src/main/java/tech/mcprison/prison/internal/inventory/PlayerInventory.java @@ -28,6 +28,14 @@ */ public interface PlayerInventory extends Inventory { + + public ItemStack[] getContents(); + public void setContents( ItemStack[] items ); + + public ItemStack[] getExtraContents(); + public void setExtraContents( ItemStack[] items ); + + /** * Gets the armor this player is wearing * diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotPlayer.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotPlayer.java index d1dd9ed9d..47157a008 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotPlayer.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotPlayer.java @@ -230,7 +230,10 @@ public org.bukkit.entity.Player getWrapper() { @Override public Inventory getInventory() { - return new SpigotPlayerInventory(getWrapper().getInventory()); + return getSpigotPlayerInventory(); + } + public SpigotPlayerInventory getSpigotPlayerInventory() { + return new SpigotPlayerInventory(getWrapper().getInventory()); } @Override public void updateInventory() { diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/inventory/SpigotPlayerInventory.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/inventory/SpigotPlayerInventory.java index 840eab86b..14649eeb5 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/inventory/SpigotPlayerInventory.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/inventory/SpigotPlayerInventory.java @@ -23,6 +23,7 @@ import java.util.List; import tech.mcprison.prison.internal.ItemStack; +import tech.mcprison.prison.internal.block.PrisonBlock; import tech.mcprison.prison.internal.inventory.PlayerInventory; import tech.mcprison.prison.spigot.SpigotUtil; import tech.mcprison.prison.spigot.block.SpigotItemStack; @@ -31,20 +32,161 @@ /** * Created by DMP9 on 04/02/2017. */ -public class SpigotPlayerInventory extends SpigotInventory implements PlayerInventory { +public class SpigotPlayerInventory + extends SpigotInventory + implements PlayerInventory { public SpigotPlayerInventory(org.bukkit.inventory.PlayerInventory wrapper) { super(wrapper); } - @Override public ItemStack[] getArmorContents() { + /** + *

This function gets all of the player's contents from the getContents(), + * getExtraContents(), and getArmorContents(). + *

+ * + * @return + */ + public List getAllContents() { + List results = new ArrayList<>(); + + for ( ItemStack iStack : getContents() ) { + if ( iStack != null ) { + results.add(iStack); + } + } + + try { + for ( ItemStack iStack : getExtraContents() ) { + if ( iStack != null ) { + results.add(iStack); + } + } + } catch (NoSuchMethodError e) { + // Ignore on older versions of spigot... Spigot 1.8.8 does not have this function. + } + + // then remove the armor ItemStacks: + for ( ItemStack iStack : getArmorContents() ) { + if ( iStack != null ) { + results.remove(iStack); + } + } + + return results; + } + + @Override + public void removeItem( ItemStack... iStack ) { + if ( iStack != null ) { + + // Remove all items... + super.removeItem(iStack); + + // But since this is a player's inventory, try to remove them from the players slots + for (ItemStack itemStack : iStack) { + PrisonBlock pBlock = itemStack.getMaterial(); + + if ( isPrisonBlockEqual( pBlock, getBoots() ) ) { + setBoots( new SpigotItemStack( 0, PrisonBlock.AIR ) ); + } + if ( isPrisonBlockEqual( pBlock, getChestplate() ) ) { + setChestplate( new SpigotItemStack( 0, PrisonBlock.AIR ) ); + } + if ( isPrisonBlockEqual( pBlock, getHelmet() ) ) { + setHelmet( new SpigotItemStack( 0, PrisonBlock.AIR ) ); + } + if ( isPrisonBlockEqual( pBlock, getLeggings() ) ) { + setLeggings( new SpigotItemStack( 0, PrisonBlock.AIR ) ); + } + + try { + + if ( isPrisonBlockEqual( pBlock, getItemInLeftHand() ) ) { + setItemInLeftHand( new SpigotItemStack( 0, PrisonBlock.AIR ) ); + } + } + catch ( Exception e ) { + // java 1.8 may not be able to handle this + } + try { + + if ( isPrisonBlockEqual( pBlock, getItemInRightHand() ) ) { + setItemInRightHand( new SpigotItemStack( 0, PrisonBlock.AIR ) ); + } + } + catch ( Exception e ) { + // java 1.8 may not be able to handle this + } + + } + } + } + + + private boolean isPrisonBlockEqual( PrisonBlock pBlock, ItemStack iStack ) { + boolean results = false; + + if ( pBlock != null && iStack != null ) { + results = pBlock.equals( iStack.getMaterial() ); + } + + return results; + } + + @Override + public ItemStack[] getContents() { + List items = new ArrayList<>(); + Arrays.asList(((org.bukkit.inventory.PlayerInventory) getWrapper()).getContents()) + .forEach(x -> items.add(SpigotUtil.bukkitItemStackToPrison(x))); + return (ItemStack[]) items.toArray(); + } + + @Override + public void setContents( ItemStack[] items ) { + List stacks = new ArrayList<>(); + Arrays.asList(items).forEach(x -> stacks.add(SpigotUtil.prisonItemStackToBukkit(x))); + ((org.bukkit.inventory.PlayerInventory) getWrapper()) + .setContents((org.bukkit.inventory.ItemStack[]) stacks.toArray()); + } + + @Override + public ItemStack[] getExtraContents() { + try { + List items = new ArrayList<>(); + Arrays.asList(((org.bukkit.inventory.PlayerInventory) getWrapper()).getExtraContents()) + .forEach(x -> items.add(SpigotUtil.bukkitItemStackToPrison(x))); + return (ItemStack[]) items.toArray(); + } + catch ( Exception e ) { + return null; + } + } + @Override + public void setExtraContents( ItemStack[] items ) { + try { + List stacks = new ArrayList<>(); + Arrays.asList(items).forEach(x -> stacks.add(SpigotUtil.prisonItemStackToBukkit(x))); + ((org.bukkit.inventory.PlayerInventory) getWrapper()) + .setExtraContents((org.bukkit.inventory.ItemStack[]) stacks.toArray()); + } + catch ( Exception e ) { + // extraContents does not exist in spigot 1.8 + } + } + + + + @Override + public ItemStack[] getArmorContents() { List items = new ArrayList<>(); Arrays.asList(((org.bukkit.inventory.PlayerInventory) getWrapper()).getArmorContents()) .forEach(x -> items.add(SpigotUtil.bukkitItemStackToPrison(x))); return (ItemStack[]) items.toArray(); } - @Override public void setArmorContents(ItemStack[] items) { + @Override + public void setArmorContents(ItemStack[] items) { List stacks = new ArrayList<>(); Arrays.asList(items).forEach(x -> stacks.add(SpigotUtil.prisonItemStackToBukkit(x))); ((org.bukkit.inventory.PlayerInventory) getWrapper()) @@ -119,7 +261,8 @@ public SpigotPlayerInventory(org.bukkit.inventory.PlayerInventory wrapper) { } } - @Override public ItemStack getItemInRightHand() { + @Override + public ItemStack getItemInRightHand() { return SpigotUtil.bukkitItemStackToPrison( @@ -127,7 +270,8 @@ public SpigotPlayerInventory(org.bukkit.inventory.PlayerInventory wrapper) { ((org.bukkit.inventory.PlayerInventory) getWrapper()) )); } - @Override public void setItemInRightHand(ItemStack stack) { + @Override + public void setItemInRightHand(ItemStack stack) { if ( stack instanceof SpigotItemStack ) { @@ -135,5 +279,5 @@ public SpigotPlayerInventory(org.bukkit.inventory.PlayerInventory wrapper) { .setItemStackInMainHand( this, ((SpigotItemStack) stack) ); } } - + } From a2a39ba793201b6b94dbc92519540fbf3ed9609d Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Thu, 13 Jul 2023 00:29:50 -0400 Subject: [PATCH 012/151] Major rewrites to sellall to utilize more of Prison's internal classes and to get away from XMaterial since it cannot handle custom blocks. A lot of sellall code has been eliminated, but no loss in functionality. Actually new functions and enhancements have been added. Eliminated the two step process of selling... where it first calculated the values, then after the fact, would try to remove the items with no "validation" that the items removed were the items that calculated the sales amount. Sellall commands: moved the '/sellall trigger add' and '/sellall trigger remove' to under the '/sell set' section since they were hidden because '/sellall trigger' was a command and many did not realize they have to use the 'help' keyword to show the others. --- .../prison/spigot/api/PrisonSpigotAPI.java | 3 +- .../autofeatures/AutoManagerFeatures.java | 2 +- .../commands/PrisonSpigotSellAllCommands.java | 40 +- .../prison/spigot/sellall/SellAllData.java | 114 + .../prison/spigot/sellall/SellAllUtil.java | 1825 ++++++++++------- 5 files changed, 1247 insertions(+), 737 deletions(-) create mode 100644 prison-spigot/src/main/java/tech/mcprison/prison/spigot/sellall/SellAllData.java diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/api/PrisonSpigotAPI.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/api/PrisonSpigotAPI.java index f6a11d90a..dc86a4839 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/api/PrisonSpigotAPI.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/api/PrisonSpigotAPI.java @@ -468,7 +468,8 @@ public Double getSellAllMoneyWithMultiplier(Player player){ } if (sellAll != null){ - return sellAll.getSellMoney(player); + return sellAll.getPlayerInventoryValue( (SpigotPlayer)player ); +// return sellAll.getSellMoney(player); } return null; diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerFeatures.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerFeatures.java index 5cb7def89..0e86d2647 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerFeatures.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerFeatures.java @@ -891,7 +891,7 @@ protected int autoPickup( PrisonMinesBlockBreakEvent pmEvent, if ( Output.get().isDebug() && isSellallEnabled ) { // Just get the calculated value for the drops... do not sell: - double amount = SellAllUtil.get().getSellMoney( player, itemStack ); + double amount = SellAllUtil.get().getItemStackValue( (SpigotPlayer)player, itemStack ); autosellTotal += amount; debugInfo.append( "(Debug-unsold-value-check: " + itemStack.getName() + diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/commands/PrisonSpigotSellAllCommands.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/commands/PrisonSpigotSellAllCommands.java index 45ac395d3..b8b5dd928 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/commands/PrisonSpigotSellAllCommands.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/commands/PrisonSpigotSellAllCommands.java @@ -17,14 +17,15 @@ import tech.mcprison.prison.commands.Wildcard; import tech.mcprison.prison.integration.EconomyCurrencyIntegration; import tech.mcprison.prison.internal.CommandSender; +import tech.mcprison.prison.internal.block.PrisonBlock; import tech.mcprison.prison.output.ChatDisplay; import tech.mcprison.prison.output.Output; import tech.mcprison.prison.sellall.messages.SpigotVariousGuiMessages; import tech.mcprison.prison.spigot.SpigotPlatform; import tech.mcprison.prison.spigot.SpigotPrison; +import tech.mcprison.prison.spigot.block.SpigotItemStack; import tech.mcprison.prison.spigot.compat.Compatibility; import tech.mcprison.prison.spigot.configs.MessagesConfig; -import tech.mcprison.prison.spigot.game.SpigotOfflinePlayer; import tech.mcprison.prison.spigot.game.SpigotPlayer; import tech.mcprison.prison.spigot.gui.sellall.SellAllAdminBlocksGUI; import tech.mcprison.prison.spigot.sellall.SellAllBlockData; @@ -391,7 +392,8 @@ public void sellAllSell(Player p){ } - @Command(identifier = "sellall delaysell", description = "Like SellAll Sell command but this will be delayed for some " + + @Command(identifier = "sellall delaysell", + description = "Like SellAll Sell command but this will be delayed for some " + "seconds and if sellall sell commands are triggered during this delay, " + "they will sum up to the total value that will be visible in a notification at the end of the delay. " + "Running more of these commands before a delay have been completed won't reset it and will do the same of /sellall sell " + @@ -573,7 +575,7 @@ private void sellAllAddCommand(CommandSender sender, } if (sellAllUtil.addSellAllBlock(blockAdd, value)){ - Output.get().sendInfo(sender, "&3 ITEM [" + itemID + ", " + value + " " + messages.getString(MessagesConfig.StringID.spigot_message_sellall_item_add_success)); + Output.get().sendInfo(sender, "&3 ITEM [" + itemID + ", " + value + "] " + messages.getString(MessagesConfig.StringID.spigot_message_sellall_item_add_success)); } } catch (IllegalArgumentException ex){ @@ -676,7 +678,7 @@ private void sellAllEditCommand(CommandSender sender, } if (sellAllUtil.editPrice(blockAdd, value)){ - Output.get().sendInfo(sender, "&3ITEM [" + itemID + ", " + value + " " + messages.getString(MessagesConfig.StringID.spigot_message_sellall_item_edit_success)); + Output.get().sendInfo(sender, "&3ITEM [" + itemID + ", " + value + "] " + messages.getString(MessagesConfig.StringID.spigot_message_sellall_item_edit_success)); } } catch (IllegalArgumentException ex){ @@ -826,7 +828,7 @@ private void sellAllDeleteMultiplierCommand(CommandSender sender, } } - @Command(identifier = "sellall Trigger", + @Command(identifier = "sellall trigger", description = "Toggle SellAll Shift+Right Click on a tool to trigger the /sellall sell command, " + "true -> Enabled or False -> Disabled.", permissions = "prison.admin", onlyPlayers = false) @@ -871,7 +873,7 @@ private void sellAllToolsTriggerToggle(CommandSender sender, } } - @Command(identifier = "sellall Trigger add", + @Command(identifier = "sellall set trigger add", description = "Add an Item to trigger the Shift+Right Click -> /sellall sell command.", permissions = "prison.admin", onlyPlayers = false) private void sellAllTriggerAdd(CommandSender sender, @@ -912,7 +914,7 @@ private void sellAllTriggerAdd(CommandSender sender, } } - @Command(identifier = "sellall Trigger delete", + @Command(identifier = "sellall set trigger delete", description = "Delete an Item from the Shift+Right Click trigger -> /sellall sell command.", permissions = "prison.admin", onlyPlayers = false) private void sellAllTriggerDelete(CommandSender sender, @@ -981,22 +983,22 @@ private void sellAllListItems( CommandSender sender ) { return; } - TreeMap items = new TreeMap<>( sellAllUtil.getSellAllBlocks() ); + TreeMap items = new TreeMap<>( sellAllUtil.getSellAllItems() ); DecimalFormat fFmt = Prison.get().getDecimalFormat("#,##0.00"); - Set keys = items.keySet(); + Set keys = items.keySet(); int maxLenKey = 0; int maxLenVal = 0; int maxLenCode = 0; - for ( XMaterial key : keys ) { - if ( key.toString().length() > maxLenKey ) { - maxLenKey = key.toString().length(); - } - if ( key.name().length() > maxLenCode ) { - maxLenCode = key.name().length(); + for ( String key : keys ) { +// if ( key.toString().length() > maxLenKey ) { +// maxLenKey = key.toString().length(); +// } + if ( key.length() > maxLenCode ) { + maxLenCode = key.length(); } - String val = fFmt.format( items.get( key ) ); + String val = fFmt.format( items.get( key ).getSalePrice() ); if ( val.length() > maxLenVal ) { maxLenVal = val.length(); } @@ -1007,17 +1009,17 @@ private void sellAllListItems( CommandSender sender ) { int lines = 0; StringBuilder sb = new StringBuilder(); - for ( XMaterial key : keys ) { + for ( String key : keys ) { boolean first = sb.length() == 0; - Double cost = items.get( key ); + Double cost = items.get( key ).getSalePrice(); if ( !first ) { sb.append( " " ); } sb.append( String.format( "%-" + maxLenCode + "s %" + maxLenVal + "s", - key.name(), fFmt.format( cost ) ) ); + key, fFmt.format( cost ) ) ); // sb.append( String.format( "%-" + maxLenKey + "s %" + maxLenVal + "s %-" + maxLenCode + "s", // key.toString(), fFmt.format( cost ), key.name() ) ); diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/sellall/SellAllData.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/sellall/SellAllData.java new file mode 100644 index 000000000..4c639edc4 --- /dev/null +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/sellall/SellAllData.java @@ -0,0 +1,114 @@ +package tech.mcprison.prison.spigot.sellall; + +import java.text.DecimalFormat; +import java.util.List; + +import tech.mcprison.prison.internal.block.PrisonBlock; +import tech.mcprison.prison.output.Output; +import tech.mcprison.prison.spigot.game.SpigotPlayer; + +/** + *

This is a simple class that contains the times that have been sold + * and the amount that they were sold for. + *

+ * + * @author Blue + * + */ +public class SellAllData { + + private PrisonBlock prisonBlock; + private int quantity; + private double transactionAmount; + + public SellAllData( PrisonBlock pBlock, int quantity, double transactionAmount ) { + super(); + + this.prisonBlock = pBlock; + this.quantity = quantity; + this.transactionAmount = transactionAmount; + } + + public String toString() { + StringBuilder sb = new StringBuilder(); + + DecimalFormat dFmt = new DecimalFormat( "#,##0.00" ); + sb.append( getPrisonBlock().getBlockName() ) + .append( ":" ) + .append( getQuantity() ) + .append( ":" ) + .append( dFmt.format(getTransactionAmount()) ); + + return sb.toString(); + } + + + public static void debugItemsSold( List soldItems, SpigotPlayer sPlayer, double multiplier ) { + if ( Output.get().isDebug() ) { + String report = SellAllData.itemsSoldReport( soldItems, sPlayer, multiplier ); + Output.get().logInfo( report ); + } + } + + public static String itemsSoldReport( List soldItems, SpigotPlayer sPlayer, double multiplier ) { + StringBuilder sb = new StringBuilder(); + StringBuilder sbItems = new StringBuilder(); + + double totalAmount = 0; + int itemCount = 0; + for (SellAllData soldItem : soldItems) { + if ( soldItem != null ) { + + totalAmount += soldItem.getTransactionAmount(); + itemCount += soldItem.getQuantity(); + + if ( sbItems.length() > 0 ) { + + sbItems.append( ", " ); + } + sbItems.append( soldItem.toString() ); + } + } + + DecimalFormat dFmt = new DecimalFormat( "#,##0.00" ); + DecimalFormat iFmt = new DecimalFormat( "#,##0" ); + + sb.append( "Transaction log: " ) + .append( sPlayer.getName() ) + .append( " multiplier: " ) + .append( dFmt.format(multiplier) ) + .append( " ItemStacks: " ) + .append( soldItems.size() ) + .append( " ItemCount: " ) + .append( iFmt.format(itemCount) ) + .append( " TotalAmount: " ) + .append( dFmt.format( totalAmount )) + .append( " [" ) + .append( sbItems ) + .append("]"); + + return sb.toString(); + } + + public PrisonBlock getPrisonBlock() { + return prisonBlock; + } + public void setPrisonBlock(PrisonBlock prisonBlock) { + this.prisonBlock = prisonBlock; + } + + public int getQuantity() { + return quantity; + } + public void setQuantity(int quantity) { + this.quantity = quantity; + } + + public double getTransactionAmount() { + return transactionAmount; + } + public void setTransactionAmount(double transactionAmount) { + this.transactionAmount = transactionAmount; + } + +} diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/sellall/SellAllUtil.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/sellall/SellAllUtil.java index edc4b85d4..5dd5c09b2 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/sellall/SellAllUtil.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/sellall/SellAllUtil.java @@ -9,27 +9,22 @@ import java.util.Optional; import org.bukkit.Bukkit; -import org.bukkit.Material; import org.bukkit.Sound; import org.bukkit.configuration.Configuration; import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.entity.Player; -import org.bukkit.inventory.Inventory; import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.PlayerInventory; import com.cryptomorin.xseries.XMaterial; import com.cryptomorin.xseries.XSound; -import at.pcgamingfreaks.Minepacks.Bukkit.API.Backpack; import tech.mcprison.prison.Prison; import tech.mcprison.prison.PrisonAPI; import tech.mcprison.prison.autofeatures.AutoFeaturesFileConfig.AutoFeatures; import tech.mcprison.prison.autofeatures.AutoFeaturesWrapper; import tech.mcprison.prison.integration.EconomyCurrencyIntegration; import tech.mcprison.prison.internal.block.PrisonBlock; -import tech.mcprison.prison.internal.block.PrisonBlock.PrisonBlockType; import tech.mcprison.prison.output.Output; import tech.mcprison.prison.ranks.PrisonRanks; import tech.mcprison.prison.ranks.data.PlayerRank; @@ -37,16 +32,12 @@ import tech.mcprison.prison.ranks.data.RankPlayer; import tech.mcprison.prison.sellall.messages.SpigotVariousGuiMessages; import tech.mcprison.prison.spigot.SpigotPrison; -import tech.mcprison.prison.spigot.backpacks.BackpacksUtil; import tech.mcprison.prison.spigot.block.SpigotItemStack; -import tech.mcprison.prison.spigot.compat.Compatibility; -import tech.mcprison.prison.spigot.compat.SpigotCompatibility; //import tech.mcprison.prison.spigot.configs.MessagesConfig; import tech.mcprison.prison.spigot.game.SpigotCommandSender; import tech.mcprison.prison.spigot.game.SpigotPlayer; import tech.mcprison.prison.spigot.gui.sellall.SellAllAdminGUI; import tech.mcprison.prison.spigot.gui.sellall.SellAllPlayerGUI; -import tech.mcprison.prison.spigot.integrations.IntegrationMinepacksPlugin; import tech.mcprison.prison.spigot.inventory.SpigotPlayerInventory; import tech.mcprison.prison.util.Text; @@ -58,12 +49,14 @@ public class SellAllUtil private static SellAllUtil instance; - private final Compatibility compat = SpigotPrison.getInstance().getCompatibility(); +// private final Compatibility compat = SpigotPrison.getInstance().getCompatibility(); - private final ItemStack lapisLazuli = compat.getLapisItemStack(); +// private final ItemStack lapisLazuli = compat.getLapisItemStack(); public Configuration sellAllConfig; - private HashMap sellAllBlocks; + private HashMap sellAllItems; +// private HashMap sellAllBlocks; + private HashMap sellAllPrestigeMultipliers; private HashMap autoSellEarningsNotificationWaiting = new HashMap<>(); private ArrayList sellAllItemTriggers; @@ -129,15 +122,103 @@ public static SellAllUtil get() { } return instance; } - + /** - * Return boolean value from String. - * - * @return boolean. + * Init options that will be cached. * */ - private static boolean getBoolean(String string) { - return string != null && string.equalsIgnoreCase("true"); + private void initCachedData() { + sellAllConfig = SpigotPrison.getInstance().updateSellAllConfig(); +// messages = SpigotPrison.getInstance().getMessagesConfig(); + permissionSellAllSell = sellAllConfig.getString("Options.Sell_Permission"); + permissionBypassSign = sellAllConfig.getString("Options.SellAll_By_Sign_Bypass_Permission"); + permissionUseSign = sellAllConfig.getString("Options.SellAll_Sign_Use_Permission"); + permissionGUI = sellAllConfig.getString("Options.GUI_Permission"); + permissionPlayerGUI = sellAllConfig.getString("Options.Player_GUI_Permission"); + permissionPrefixBlocks = sellAllConfig.getString("Options.Sell_Per_Block_Permission"); + permissionAutoSellPerUserToggleable = sellAllConfig.getString("Options.Full_Inv_AutoSell_PerUserToggleable_Permission"); + permissionItemTrigger = sellAllConfig.getString("Options.ShiftAndRightClickSellAll.Permission"); + sellAllCurrency = sellAllConfig.getString("Options.SellAll_Currency"); + sellAllSoundSuccess = XSound.matchXSound("Options.Sell_Sound_Success_Name").orElse(XSound.ENTITY_PLAYER_LEVELUP).parseSound(); + sellAllSoundFail = XSound.matchXSound("Options.Sell_Sound_Fail_Name").orElse(XSound.BLOCK_ANVIL_PLACE).parseSound(); + sellAllSignTag = Text.translateAmpColorCodes(sellAllConfig.getString("Options.SellAll_Sign_Visible_Tag") ); +// sellAllBlocks = initSellAllBlocks(); + sellAllItems = initSellAllItems(); + + sellAllPrestigeMultipliers = initPrestigeMultipliers(); + sellAllItemTriggers = initSellAllItemTrigger(); +// sellAllDisabledWorlds = initSellAllDisabledWorlds(); + defaultMultiplier = Double.parseDouble(sellAllConfig.getString("Options.Multiplier_Default")); + defaultSellAllDelay = Integer.parseInt(sellAllConfig.getString("Options.Sell_Delay_Seconds")); + defaultAutoSellEarningNotificationDelay = Integer.parseInt(sellAllConfig.getString("Options.Full_Inv_AutoSell_EarnedMoneyNotificationDelay_Delay_Seconds")); + isPerBlockPermissionEnabled = getBooleanValue("Options.Sell_Per_Block_Permission_Enabled"); + isAutoSellEnabled = getBooleanValue("Options.Full_Inv_AutoSell"); + isAutoSellNotificationEnabled = getBooleanValue("Options.Full_Inv_AutoSell_Notification"); + isAutoSellEarningNotificationDelayEnabled = getBooleanValue("Options.Full_Inv_AutoSell_EarnedMoneyNotificationDelay_Enabled"); + isAutoSellPerUserToggleable = getBooleanValue("Options.Full_Inv_AutoSell_perUserToggleable"); + isAutoSellPerUserToggleablePermEnabled = getBooleanValue("Options.Full_Inv_AutoSell_perUserToggleable_Need_Perm"); + isSellAllNotificationEnabled = getBooleanValue("Options.Sell_Notify_Enabled"); + isSellAllSoundEnabled = getBooleanValue("Options.Sell_Sound_Enabled"); + isSellAllBackpackItemsEnabled = getBooleanValue("Options.Sell_Prison_BackPack_Items"); + isSellAllMinesBackpacksPluginEnabled = getBooleanValue("Options.Sell_MinesBackPacks_Plugin_Backpack"); + isSellAllDelayEnabled = getBooleanValue("Options.Sell_Delay_Enabled"); + isSellAllSellPermissionEnabled = getBooleanValue("Options.Sell_Permission_Enabled"); + isSellAllItemTriggerEnabled = getBooleanValue("Options.ShiftAndRightClickSellAll.Enabled"); + isSellAllItemTriggerPermissionEnabled = getBooleanValue("Options.ShiftAndRightClickSellAll.PermissionEnabled"); + isSellAllGUIEnabled = getBooleanValue("Options.GUI_Enabled"); + isSellAllPlayerGUIEnabled = getBooleanValue("Options.Player_GUI_Enabled"); + isSellAllGUIPermissionEnabled = getBooleanValue("Options.GUI_Permission_Enabled"); + isSellAllPlayerGUIPermissionEnabled = getBooleanValue("Options.Player_GUI_Permission_Enabled"); + isSellAllMultiplierEnabled = getBooleanValue("Options.Multiplier_Enabled"); + isSellAllPermissionMultiplierOnlyHigherEnabled = getBooleanValue("Options.Multiplier_Permission_Only_Higher"); + isSellAllSignEnabled = getBooleanValue("Options.SellAll_Sign_Enabled"); + isSellAllSignNotifyEnabled = getBooleanValue("Options.SellAll_Sign_Notify"); + isSellAllSignPermissionToUseEnabled = getBooleanValue("Options.SellAll_Sign_Use_Permission_Enabled"); + isSellAllBySignOnlyEnabled = getBooleanValue("Options.SellAll_By_Sign_Only"); + isSellAllHandEnabled = getBooleanValue("Options.SellAll_Hand_Enabled"); + + isSellAllIgnoreCustomNames = getBooleanValue("Options.SellAll_ignoreCustomNames", false); } + + private boolean getBooleanValue( String configName ) { + return getBooleanValue(configName, false); + } + private boolean getBooleanValue( String configName, Boolean defaultValue ) { + boolean results = (defaultValue == null ? false : defaultValue.booleanValue() ); + + if ( configName != null ) { + if ( sellAllConfig.isString(configName) ) { + String boolVal = sellAllConfig.getString(configName); + if ( boolVal != null ) { + // Boolean.parseBoolean() also supports yes and no so don't pretest for true/false. + try { + results = Boolean.parseBoolean(boolVal); + } catch (Exception e) { + // Not a boolean value, so ignore and let the "defaut" value stand + } + } + else { + // ignore since it's not a boolean value and let the "default" value stand + } + } + else if ( sellAllConfig.isBoolean(configName) ) { + results = sellAllConfig.getBoolean(configName, results); + } + else { + // Ignore since the config is not boolean or a String that "could" be a boolean + } + } + + return results; + } + +// /** +// * Return boolean value from String. +// * +// * @return boolean. +// * */ +// private static boolean getBoolean(String string) { +// return string != null && string.equalsIgnoreCase("true"); +// } /** * Get an ArrayList of SellAllItemTriggers as XMaterials. @@ -172,60 +253,68 @@ public ArrayList getItemTriggerXMaterials(){ // return materials; // } - /** - * Get SellAll XMaterial or Lapis (As Lapis is weird) from an ItemStack. - * - * @param itemStack - ItemStack. - * - * @return XMaterial. - * */ - private XMaterial getXMaterialOrLapis(ItemStack itemStack) { - XMaterial results = null; - - String altName = null; - - if ( itemStack.hasItemMeta() && itemStack.getItemMeta().hasDisplayName() ) { - altName = itemStack.getItemMeta().getDisplayName(); - } - - if ( altName == null || isSellAllIgnoreCustomNames ) { - XMaterial xMat = null; - - if (itemStack.isSimilar(lapisLazuli)) { - xMat = XMaterial.LAPIS_LAZULI; - } - else { - - try - { - xMat = XMaterial.matchXMaterial(itemStack); - } - catch ( Exception e ) - { - // ignore... it is not normal matertial so it cannot be sold - } - } - if ( xMat != null ) { - - // When converted over to be based upon a String name, instead of XMaterial, - // the altName will take priority over the XMaterial name. - results = xMat; - } - } - - return results; - } +// /** +// * Get SellAll XMaterial or Lapis (As Lapis is weird) from an ItemStack. +// * +// * @param itemStack - ItemStack. +// * +// * @return XMaterial. +// * */ +// private XMaterial getXMaterialOrLapis(ItemStack itemStack) { +// XMaterial results = null; +// +// String altName = null; +// +// if ( itemStack.hasItemMeta() && itemStack.getItemMeta().hasDisplayName() ) { +// altName = itemStack.getItemMeta().getDisplayName(); +// } +// +// if ( altName == null || isSellAllIgnoreCustomNames ) { +// XMaterial xMat = null; +// +// if (itemStack.isSimilar(lapisLazuli)) { +// xMat = XMaterial.LAPIS_LAZULI; +// } +// else { +// +// try +// { +// xMat = XMaterial.matchXMaterial(itemStack); +// } +// catch ( Exception e ) +// { +// // ignore... it is not normal matertial so it cannot be sold +// } +// } +// if ( xMat != null ) { +// +// // When converted over to be based upon a String name, instead of XMaterial, +// // the altName will take priority over the XMaterial name. +// results = xMat; +// } +// } +// +// return results; +// } - /** - * Return SellAll Blocks HashMap cached values. - * - * @return HashMap of XMaterial-Double. - * */ - public HashMap getSellAllBlocks() { - return sellAllBlocks; - } +// /** +// * Return SellAll Blocks HashMap cached values. +// * +// * @return HashMap of XMaterial-Double. +// * */ +// public HashMap getSellAllBlocks() { +// return sellAllBlocks; +// } /** + * + * @return HashMap + */ + public HashMap getSellAllItems() { + return sellAllItems; + } + + /** * Return SellAll Prestige Multiplier HashMap read before from config on init. * * HashMap details: @@ -238,64 +327,64 @@ public HashMap getPrestigeMultipliers() { return sellAllPrestigeMultipliers; } - /** - * Get HashMap of XMaterials and amounts from an Inventory. - * - * @param inv - Inventory. - * - * @return HashMap of XMaterials and Integers. - * */ - public HashMap getXMaterialsHashMapFromInventory(Inventory inv){ - - HashMap xMaterialIntegerHashMap = new HashMap<>(); - for (ItemStack itemStack : inv.getContents()){ - if (itemStack != null){ - XMaterial xMaterial = getXMaterialOrLapis(itemStack); - if ( xMaterial != null ) { - - if (xMaterialIntegerHashMap.containsKey(xMaterial) && xMaterialIntegerHashMap.get(xMaterial) != 0){ - xMaterialIntegerHashMap.put(xMaterial, xMaterialIntegerHashMap.get(xMaterial) + itemStack.getAmount()); - } - else { - xMaterialIntegerHashMap.put(xMaterial, itemStack.getAmount()); - } - } - } - } - - return xMaterialIntegerHashMap; - } - +// /** +// * Get HashMap of XMaterials and amounts from an Inventory. +// * +// * @param inv - Inventory. +// * +// * @return HashMap of XMaterials and Integers. +// * */ +// private HashMap getXMaterialsHashMapFromInventory(Inventory inv){ +// +// HashMap xMaterialIntegerHashMap = new HashMap<>(); +// for (ItemStack itemStack : inv.getContents()){ +// if (itemStack != null){ +// XMaterial xMaterial = getXMaterialOrLapis(itemStack); +// if ( xMaterial != null ) { +// +// if (xMaterialIntegerHashMap.containsKey(xMaterial) && xMaterialIntegerHashMap.get(xMaterial) != 0){ +// xMaterialIntegerHashMap.put(xMaterial, xMaterialIntegerHashMap.get(xMaterial) + itemStack.getAmount()); +// } +// else { +// xMaterialIntegerHashMap.put(xMaterial, itemStack.getAmount()); +// } +// } +// } +// } +// +// return xMaterialIntegerHashMap; +// } - /** - * get HashMap of XMaterials and Amounts from an ArrayList of ItemStacks. - * - * @param itemStacks - ArrayList of ItemStacks. - * - * @return HashMap of XMaterials and Integers. - * */ - public HashMap getXMaterialsHashMapFromArrayList(ArrayList itemStacks){ - - HashMap xMaterialIntegerHashMap = new HashMap<>(); - for (ItemStack itemStack : itemStacks){ - if (itemStack != null){ - try { - XMaterial xMaterial = getXMaterialOrLapis(itemStack); - if ( xMaterial != null ) { - - if (xMaterialIntegerHashMap.containsKey(xMaterial) && xMaterialIntegerHashMap.get(xMaterial) != 0) { - xMaterialIntegerHashMap.put(xMaterial, xMaterialIntegerHashMap.get(xMaterial) + itemStack.getAmount()); - } - else { - xMaterialIntegerHashMap.put(xMaterial, itemStack.getAmount()); - } - } - } catch (IllegalArgumentException ignored){} - } - } - return xMaterialIntegerHashMap; - } +// /** +// * get HashMap of XMaterials and Amounts from an ArrayList of ItemStacks. +// * +// * @param itemStacks - ArrayList of ItemStacks. +// * +// * @return HashMap of XMaterials and Integers. +// * */ +// private HashMap getXMaterialsHashMapFromArrayList(ArrayList itemStacks){ +// +// HashMap xMaterialIntegerHashMap = new HashMap<>(); +// for (ItemStack itemStack : itemStacks){ +// if (itemStack != null){ +// try { +// XMaterial xMaterial = getXMaterialOrLapis(itemStack); +// if ( xMaterial != null ) { +// +// if (xMaterialIntegerHashMap.containsKey(xMaterial) && xMaterialIntegerHashMap.get(xMaterial) != 0) { +// xMaterialIntegerHashMap.put(xMaterial, xMaterialIntegerHashMap.get(xMaterial) + itemStack.getAmount()); +// } +// else { +// xMaterialIntegerHashMap.put(xMaterial, itemStack.getAmount()); +// } +// } +// } catch (IllegalArgumentException ignored){} +// } +// } +// +// return xMaterialIntegerHashMap; +// } /** * Get SellAll Player Multiplier. @@ -389,257 +478,410 @@ public double getPlayerMultiplier(Player p){ return multiplier; } - /** - * Get SellAll Money to give, it requires Player because of SellAll perBlockPermission as an option. - * NOTE: This WON'T remove blocks from the HashMap when sold, and won't edit Inventories of Players, - * but only return the amount of money that the Player would get if he sells now everything from the - * specified HashMap of XMaterials and Integers. - * - * Will also calculate the Multiplier of the Player. - * - * Get SellAll Sell value of HashMap values. - * NOTE: If there aren't blocks in the SellAll shop this will return 0. - * NOTE: This method WON'T remove blocks from HashMap, but only return a double value. - * - * @param p - Player. - * @param xMaterialIntegerHashMap - HashMap of XMaterial-Integer (Blocks of origin). - * - * @return double. - * */ - public double getSellMoney(Player p, HashMap xMaterialIntegerHashMap){ - StringBuilder sb = new StringBuilder(); - boolean debug = Output.get().isDebug(); +// /** +// * Get SellAll Money to give, it requires Player because of SellAll perBlockPermission as an option. +// * NOTE: This WON'T remove blocks from the HashMap when sold, and won't edit Inventories of Players, +// * but only return the amount of money that the Player would get if he sells now everything from the +// * specified HashMap of XMaterials and Integers. +// * +// * Will also calculate the Multiplier of the Player. +// * +// * Get SellAll Sell value of HashMap values. +// * NOTE: If there aren't blocks in the SellAll shop this will return 0. +// * NOTE: This method WON'T remove blocks from HashMap, but only return a double value. +// * +// * @param p - Player. +// * @param xMaterialIntegerHashMap - HashMap of XMaterial-Integer (Blocks of origin). +// * +// * @return double. +// * */ +// private double getSellMoney(Player p, HashMap xMaterialIntegerHashMap){ +// StringBuilder sb = new StringBuilder(); +// boolean debug = Output.get().isDebug(); +// +// if (sellAllItems.isEmpty()){ +// return 0; +// } +// +// double multiplier = getPlayerMultiplier(p); +// +// +// double earned = 0; +// for (HashMap.Entry xMatEntry : xMaterialIntegerHashMap.entrySet()){ +// +// PrisonBlock pBlockKey = Prison.get().getPlatform().getPrisonBlock( xMatEntry.getKey().name() ); +// +// String key = pBlockKey.getBlockName(); +// +// if (sellAllItems.containsKey( key )){ +// // This is stupid but right now I'm too confused, sorry. +// if (isPerBlockPermissionEnabled && !p.hasPermission(permissionPrefixBlocks + key )){ +// // Nothing will change. +// } +// else { +// PrisonBlock pBlock = sellAllItems.get(key); +// +//// XMaterial xMat = xMatEntry.getKey(); +// int qty = xMatEntry.getValue(); +// double value = pBlock.getSalePrice(); +// +// if ( debug ) { +// +// if ( sb.length() > 0 ) { +// sb.append(", "); +// } +// sb.append( key.toLowerCase() ).append(":") +// .append( qty ).append("@").append(value); +// } +// +// earned += qty * value; +// } +// } +// } +// +// double total = earned * multiplier; +// +// if ( debug ) { +// DecimalFormat dFmt = Prison.get().getDecimalFormat( "#,##0.00" ); +// sb.append( " earned: " ).append( dFmt.format(earned) ) +// .append( " mult: " ).append( dFmt.format(multiplier) ) +// .append( " total: " ).append( dFmt.format(total) ); +// String message = String.format( +// "Sellall.getSellMoney: %s %s", +// p.getName(), sb.toString() ); +// Output.get().logInfo(message); +// } +// +// return total; +// } - if (sellAllBlocks.isEmpty()){ - return 0; - } +// /** +// * Get SellAll Money to give, it requires Player because of SellAll perBlockPermission as an option. +// * NOTE: This WON'T remove blocks from the ArrayList when sold, and won't edit Inventories of Players, +// * but only return the amount of money that the Player would get if he sells now everything from the +// * specified ArrayList of ItemStacks. +// * +// * Will also calculate the Multiplier of the Player. +// * +// * Get SellAll Sell value of ArrayList of itemstack. +// * NOTE: If there aren't blocks in the SellAll shop this will return 0. +// * NOTE: This method WON'T remove blocks from HashMap, but only return a double value. +// * +// * @param p - Player. +// * @param itemStacks - ArrayList of ItemStacks (Blocks of origin). +// * +// * @return double. +// * */ +// private double getSellMoney(Player p, ArrayList itemStacks){ +// HashMap xMaterialIntegerHashMap = getXMaterialsHashMapFromArrayList(itemStacks); +// return getSellMoney(p, xMaterialIntegerHashMap); +// } + + + public double getPlayerInventoryValue( SpigotPlayer sPlayer ) { + double value = 0; + + double multiplier = getPlayerMultiplier(sPlayer.getWrapper()); - double multiplier = getPlayerMultiplier(p); - - - double earned = 0; - for (HashMap.Entry xMatEntry : xMaterialIntegerHashMap.entrySet()){ - if (sellAllBlocks.containsKey(xMatEntry.getKey())){ - // This is stupid but right now I'm too confused, sorry. - if (isPerBlockPermissionEnabled && !p.hasPermission(permissionPrefixBlocks + xMatEntry.getKey().name())){ - // Nothing will change. - } - else { - XMaterial xMat = xMatEntry.getKey(); - int qty = xMatEntry.getValue(); - double value = sellAllBlocks.get(xMat); - - if ( debug ) { - - if ( sb.length() > 0 ) { - sb.append(", "); - } - sb.append( xMat.name().toLowerCase() ).append(":") - .append( qty ).append("@").append(value); - } - - earned += qty * value; - } - } - } + SpigotPlayerInventory spInventory = sPlayer.getSpigotPlayerInventory(); - double total = earned * multiplier; - - if ( debug ) { - DecimalFormat dFmt = Prison.get().getDecimalFormat( "#,##0.00" ); - sb.append( " earned: " ).append( dFmt.format(earned) ) - .append( " mult: " ).append( dFmt.format(multiplier) ) - .append( " total: " ).append( dFmt.format(total) ); - String message = String.format( - "Sellall.getSellMoney: %s %s", - p.getName(), sb.toString() ); - Output.get().logInfo(message); - } - - return total; + List soldItems = valueOfInventoryItems( spInventory, multiplier ); + for (SellAllData soldItem : soldItems) { + value += soldItem.getTransactionAmount(); + } + + return value; } - - /** - * Get SellAll Money to give, it requires Player because of SellAll perBlockPermission as an option. - * NOTE: This WON'T remove blocks from the ArrayList when sold, and won't edit Inventories of Players, - * but only return the amount of money that the Player would get if he sells now everything from the - * specified ArrayList of ItemStacks. - * - * Will also calculate the Multiplier of the Player. - * - * Get SellAll Sell value of ArrayList of itemstack. - * NOTE: If there aren't blocks in the SellAll shop this will return 0. - * NOTE: This method WON'T remove blocks from HashMap, but only return a double value. - * - * @param p - Player. - * @param itemStacks - ArrayList of ItemStacks (Blocks of origin). - * - * @return double. - * */ - public double getSellMoney(Player p, ArrayList itemStacks){ - HashMap xMaterialIntegerHashMap = getXMaterialsHashMapFromArrayList(itemStacks); - return getSellMoney(p, xMaterialIntegerHashMap); + + public String getPlayerInventoryValueReport( SpigotPlayer sPlayer ) { + + double multiplier = getPlayerMultiplier(sPlayer.getWrapper()); + + SpigotPlayerInventory spInventory = sPlayer.getSpigotPlayerInventory(); + + List soldItems = valueOfInventoryItems( spInventory, multiplier ); + + String report = SellAllData.itemsSoldReport(soldItems, sPlayer, multiplier); + + return report; } - - /** - * Get SellAll Sell Money, calculated from all the enabled backpacks (from sellAll config and integrations) and - * main inventory. - * NOTE: This WON'T remove blocks from Inventories/Backpacks, but only return their value. - * - * Will also calculate the Multiplier of the Player. - * - * NOTE: If there aren't blocks in the SellAll shop this will return 0. - * NOTE: This method WON'T remove blocks from HashMap, but only return a double value. - * - * @param p - Player. - * - * @return double. - * */ - public double getSellMoney(Player p){ - - if (sellAllBlocks.isEmpty()){ - return 0; - } - - return getSellMoney(p, getHashMapOfPlayerInventories(p)); + + public double getItemStackValue( SpigotPlayer player, SpigotItemStack itemStack ) { + + double multiplier = getPlayerMultiplier(player.getWrapper()); + + SellAllData sad = sellItemStack( itemStack, multiplier ); + + return sad.getTransactionAmount(); } - /** - *

This sells a specific item stack. Actually it returns the value of an item stack, - * its up to the calling function to dispose of the contents if the result is non-zero. - *

- * @param p - * @param itemStack - * @return - */ - public double getSellMoney( Player p, SpigotItemStack itemStack ) - { - double results = 0d; + public String getItemStackValueReport( SpigotPlayer sPlayer, SpigotItemStack itemStack ) { - // Either ignore custom names, or if isSellAllIgnoreCustomNames is set, then allow them - // to be processed as they used to be processed. + double multiplier = getPlayerMultiplier(sPlayer.getWrapper()); - // For now, do not sell custom blocks since this sellall is based upon - // XMaterial and custom blocks cannot be represented by XMaterial so - // it will sell it as the wrong material - if ( isSellAllIgnoreCustomNames || - itemStack.getMaterial().getBlockType() == null || - itemStack.getMaterial().getBlockType() == PrisonBlockType.minecraft ) { - - HashMap xMaterialIntegerHashMap = new HashMap<>(); + List soldItems = new ArrayList<>(); + + SellAllData sad = sellItemStack( itemStack, multiplier ); + if ( sad != null ) { - PrisonBlock pBlock = itemStack.getMaterial(); + soldItems.add( sad ); + } + + String report = SellAllData.itemsSoldReport(soldItems, sPlayer, multiplier); + + return report; + } + + private List sellPlayerItems(Player p) { + + double multiplier = getPlayerMultiplier(p); + + SpigotPlayer sPlayer = new SpigotPlayer( p ); + + SpigotPlayerInventory spInventory = sPlayer.getSpigotPlayerInventory(); + + return sellInventoryItems( spInventory, multiplier ); + } + + private List sellInventoryItems( tech.mcprison.prison.internal.inventory.Inventory inventory, double multiplier ) { + List soldItems = new ArrayList<>(); + + if ( inventory != null ) { - XMaterial xMat = SpigotCompatibility.getInstance().getXMaterial( pBlock ); + List removable = new ArrayList<>(); - if ( xMat != null ) { - xMaterialIntegerHashMap.put( xMat, itemStack.getAmount() ); + // Go through all of the player's inventory and identify what can be sold. + // 1. if it can be sold, then create a SellAllData "receipt" + // 2. Add sad to the soldItems List + // 3. Add the ItemStack to the removable List to be removed later + for ( tech.mcprison.prison.internal.ItemStack inv : inventory.getItems() ) { - results = getSellMoney( p, xMaterialIntegerHashMap ); + SellAllData sad = sellItemStack( (SpigotItemStack)inv, multiplier ); + + if ( sad != null ) { + soldItems.add(sad); + + removable.add(inv); + } + } + + // We've identified all that could be sold, now remove them from the player's inventory + for (tech.mcprison.prison.internal.ItemStack itemStack : removable) { + inventory.removeItem( itemStack ); } } + return soldItems; + } + + private List valueOfInventoryItems( + tech.mcprison.prison.internal.inventory.Inventory inventory, double multiplier ) { + List soldItems = new ArrayList<>(); - return results; - } - + if ( inventory != null ) { + + for ( tech.mcprison.prison.internal.ItemStack inv : inventory.getItems() ) { + + SellAllData sad = sellItemStack( (SpigotItemStack)inv, multiplier ); + + if ( sad != null ) { + soldItems.add(sad); + } + } + } + + return soldItems; + } /** - *

This gets the player's inventory, ignoring the armor slots.

+ *

This takes an SpigotItemStack and generates a SellAllData items with + * the transaction amount based upon how many items are in the itemStack, + * times the salePrice, times the player's multiplier. + * This function DOES NOT remove anything from any ItemStack, any Inventory, + * or any player's inventory. This just generates the transaction. + *

* - * @param p + * @param iStack + * @param multiplier * @return */ - private List getPlayerInventory( Player p ) { + private SellAllData sellItemStack( SpigotItemStack iStack, double multiplier ) { + SellAllData soldItem = null; - return getPlayerInventory( p.getInventory() ); + if ( iStack != null ) { + + PrisonBlock pBlockInv = iStack.getMaterial(); + PrisonBlock pBlockSellAll = sellAllItems.get( pBlockInv.getBlockName().toLowerCase() ); + + if ( pBlockSellAll != null ) { + double amount = iStack.getAmount() * pBlockSellAll.getSalePrice() * multiplier; + soldItem = new SellAllData( pBlockSellAll, iStack.getAmount(), amount ); + + } + } -// List results = new ArrayList<>(); + return soldItem; + } + +// /** +// * Get SellAll Sell Money, calculated from all the enabled backpacks (from sellAll config and integrations) and +// * main inventory. +// * NOTE: This WON'T remove blocks from Inventories/Backpacks, but only return their value. +// * +// * Will also calculate the Multiplier of the Player. +// * +// * NOTE: If there aren't blocks in the SellAll shop this will return 0. +// * NOTE: This method WON'T remove blocks from HashMap, but only return a double value. +// * +// * @param p - Player. +// * +// * @return double. +// * */ +// public double getSellMoney(Player p){ +// +// if (sellAllItems.isEmpty()){ +// return 0; +// } +// +// return getSellMoney(p, getHashMapOfPlayerInventories(p)); +// } + +// /** +// *

This sells a specific item stack. Actually it returns the value of an item stack, +// * its up to the calling function to dispose of the contents if the result is non-zero. +// *

+// * @param p +// * @param itemStack +// * @return +// */ +// private double getSellMoney( Player p, SpigotItemStack itemStack ) +// { +// double results = 0d; // -// PlayerInventory inv = p.getInventory(); +// // Either ignore custom names, or if isSellAllIgnoreCustomNames is set, then allow them +// // to be processed as they used to be processed. +// +// // For now, do not sell custom blocks since this sellall is based upon +// // XMaterial and custom blocks cannot be represented by XMaterial so +// // it will sell it as the wrong material +// if ( isSellAllIgnoreCustomNames || +// itemStack.getMaterial().getBlockType() == null || +// itemStack.getMaterial().getBlockType() == PrisonBlockType.minecraft ) { +// +// HashMap xMaterialIntegerHashMap = new HashMap<>(); +// +// PrisonBlock pBlock = itemStack.getMaterial(); +// +// XMaterial xMat = SpigotCompatibility.getInstance().getXMaterial( pBlock ); +// +// if ( xMat != null ) { +// xMaterialIntegerHashMap.put( xMat, itemStack.getAmount() ); +// +// results = getSellMoney( p, xMaterialIntegerHashMap ); +// } +// } // -// for ( ItemStack iStack : inv.getStorageContents() ) { +// +// return results; +// } + + +// /** +// *

This gets the player's inventory, ignoring the armor slots.

+// * +// * @param p +// * @return +// */ +// private List getPlayerInventory( Player p ) { +// +// return getPlayerInventory( p.getInventory() ); +// +//// List results = new ArrayList<>(); +//// +//// PlayerInventory inv = p.getInventory(); +//// +//// for ( ItemStack iStack : inv.getStorageContents() ) { +//// if ( iStack != null ) { +//// results.add(iStack); +//// } +//// } +//// for ( ItemStack iStack : inv.getExtraContents() ) { +//// if ( iStack != null ) { +//// results.add(iStack); +//// } +//// } +//// +//// return results; +// } +// private List getPlayerInventory( PlayerInventory inv ) { +// List results = new ArrayList<>(); +// +// for ( ItemStack iStack : inv.getContents() ) { // if ( iStack != null ) { // results.add(iStack); // } // } -// for ( ItemStack iStack : inv.getExtraContents() ) { +// +// try { +// for ( ItemStack iStack : inv.getExtraContents() ) { +// if ( iStack != null ) { +// results.add(iStack); +// } +// } +// } catch (NoSuchMethodError e) { +// // Ignore on older versions of spigot... Spigot 1.8.8 does not have this function. +// } +// +// // then remove the armor ItemStacks: +// for ( ItemStack iStack : inv.getArmorContents() ) { // if ( iStack != null ) { -// results.add(iStack); +// results.remove(iStack); // } // } // // return results; - } - private List getPlayerInventory( PlayerInventory inv ) { - List results = new ArrayList<>(); - - for ( ItemStack iStack : inv.getContents() ) { - if ( iStack != null ) { - results.add(iStack); - } - } - - try { - for ( ItemStack iStack : inv.getExtraContents() ) { - if ( iStack != null ) { - results.add(iStack); - } - } - } catch (NoSuchMethodError e) { - // Ignore on older versions of spigot... Spigot 1.8.8 does not have this function. - } - - // then remove the armor ItemStacks: - for ( ItemStack iStack : inv.getArmorContents() ) { - if ( iStack != null ) { - results.remove(iStack); - } - } - - return results; - } +// } - /** - * Get HashMap with all the items of a Player. - * - * Return HashMap of XMaterial-Integer. - * - * @param p - Player. - * - * @return HashMap - XMaterial-Integer. - * */ - private HashMap getHashMapOfPlayerInventories(Player p) { - - HashMap xMaterialIntegerHashMap = new HashMap<>(); - - if (isSellAllBackpackItemsEnabled && getBoolean(SpigotPrison.getInstance().getConfig().getString("backpacks"))){ - - BackpacksUtil backpacksUtil = BackpacksUtil.get(); - if (backpacksUtil.isMultipleBackpacksEnabled()){ - for (String id : backpacksUtil.getBackpacksIDs(p)){ - xMaterialIntegerHashMap = addInventoryToHashMap(xMaterialIntegerHashMap, backpacksUtil.getBackpack(p, id)); - } - } else { - String id = null; - xMaterialIntegerHashMap = addInventoryToHashMap(xMaterialIntegerHashMap, - backpacksUtil.getBackpack(p, id)); - } - } - - if (isSellAllMinesBackpacksPluginEnabled && IntegrationMinepacksPlugin.getInstance().isEnabled()){ - Backpack backpack = IntegrationMinepacksPlugin.getInstance().getMinepacks().getBackpackCachedOnly(p); - if (backpack != null) { - xMaterialIntegerHashMap = addInventoryToHashMap(xMaterialIntegerHashMap, backpack.getInventory()); - backpack.setChanged(); - backpack.save(); - } - } - - xMaterialIntegerHashMap = addInventoryToHashMap(xMaterialIntegerHashMap, getPlayerInventory( p )); -// xMaterialIntegerHashMap = addInventoryToHashMap(xMaterialIntegerHashMap, p.getInventory()); - return xMaterialIntegerHashMap; - } +// /** +// * Get HashMap with all the items of a Player. +// * +// * Return HashMap of XMaterial-Integer. +// * +// * @param p - Player. +// * +// * @return HashMap - XMaterial-Integer. +// * */ +// private HashMap getHashMapOfPlayerInventories(Player p) { +// +// HashMap xMaterialIntegerHashMap = new HashMap<>(); +// +// if (isSellAllBackpackItemsEnabled && getBoolean(SpigotPrison.getInstance().getConfig().getString("backpacks"))){ +// +// BackpacksUtil backpacksUtil = BackpacksUtil.get(); +// if (backpacksUtil.isMultipleBackpacksEnabled()){ +// for (String id : backpacksUtil.getBackpacksIDs(p)){ +// xMaterialIntegerHashMap = addInventoryToHashMap(xMaterialIntegerHashMap, backpacksUtil.getBackpack(p, id)); +// } +// } else { +// String id = null; +// xMaterialIntegerHashMap = addInventoryToHashMap(xMaterialIntegerHashMap, +// backpacksUtil.getBackpack(p, id)); +// } +// } +// +// if (isSellAllMinesBackpacksPluginEnabled && IntegrationMinepacksPlugin.getInstance().isEnabled()){ +// Backpack backpack = IntegrationMinepacksPlugin.getInstance().getMinepacks().getBackpackCachedOnly(p); +// if (backpack != null) { +// xMaterialIntegerHashMap = addInventoryToHashMap(xMaterialIntegerHashMap, backpack.getInventory()); +// backpack.setChanged(); +// backpack.save(); +// } +// } +// +// xMaterialIntegerHashMap = addInventoryToHashMap(xMaterialIntegerHashMap, getPlayerInventory( p )); +//// xMaterialIntegerHashMap = addInventoryToHashMap(xMaterialIntegerHashMap, p.getInventory()); +// return xMaterialIntegerHashMap; +// } /** * Get AutoSell Player toggle if available. @@ -736,125 +978,70 @@ public void updateConfig(){ // sellAllConfig = SpigotPrison.getInstance().updateSellAllConfig(); } - /** - * Init options that will be cached. - * */ - private void initCachedData() { - sellAllConfig = SpigotPrison.getInstance().updateSellAllConfig(); -// messages = SpigotPrison.getInstance().getMessagesConfig(); - permissionSellAllSell = sellAllConfig.getString("Options.Sell_Permission"); - permissionBypassSign = sellAllConfig.getString("Options.SellAll_By_Sign_Bypass_Permission"); - permissionUseSign = sellAllConfig.getString("Options.SellAll_Sign_Use_Permission"); - permissionGUI = sellAllConfig.getString("Options.GUI_Permission"); - permissionPlayerGUI = sellAllConfig.getString("Options.Player_GUI_Permission"); - permissionPrefixBlocks = sellAllConfig.getString("Options.Sell_Per_Block_Permission"); - permissionAutoSellPerUserToggleable = sellAllConfig.getString("Options.Full_Inv_AutoSell_PerUserToggleable_Permission"); - permissionItemTrigger = sellAllConfig.getString("Options.ShiftAndRightClickSellAll.Permission"); - sellAllCurrency = sellAllConfig.getString("Options.SellAll_Currency"); - sellAllSoundSuccess = XSound.matchXSound("Options.Sell_Sound_Success_Name").orElse(XSound.ENTITY_PLAYER_LEVELUP).parseSound(); - sellAllSoundFail = XSound.matchXSound("Options.Sell_Sound_Fail_Name").orElse(XSound.BLOCK_ANVIL_PLACE).parseSound(); - sellAllSignTag = Text.translateAmpColorCodes(sellAllConfig.getString("Options.SellAll_Sign_Visible_Tag") ); - sellAllBlocks = initSellAllBlocks(); - sellAllPrestigeMultipliers = initPrestigeMultipliers(); - sellAllItemTriggers = initSellAllItemTrigger(); -// sellAllDisabledWorlds = initSellAllDisabledWorlds(); - defaultMultiplier = Double.parseDouble(sellAllConfig.getString("Options.Multiplier_Default")); - defaultSellAllDelay = Integer.parseInt(sellAllConfig.getString("Options.Sell_Delay_Seconds")); - defaultAutoSellEarningNotificationDelay = Integer.parseInt(sellAllConfig.getString("Options.Full_Inv_AutoSell_EarnedMoneyNotificationDelay_Delay_Seconds")); - isPerBlockPermissionEnabled = getBooleanValue("Options.Sell_Per_Block_Permission_Enabled"); - isAutoSellEnabled = getBooleanValue("Options.Full_Inv_AutoSell"); - isAutoSellNotificationEnabled = getBooleanValue("Options.Full_Inv_AutoSell_Notification"); - isAutoSellEarningNotificationDelayEnabled = getBooleanValue("Options.Full_Inv_AutoSell_EarnedMoneyNotificationDelay_Enabled"); - isAutoSellPerUserToggleable = getBooleanValue("Options.Full_Inv_AutoSell_perUserToggleable"); - isAutoSellPerUserToggleablePermEnabled = getBooleanValue("Options.Full_Inv_AutoSell_perUserToggleable_Need_Perm"); - isSellAllNotificationEnabled = getBooleanValue("Options.Sell_Notify_Enabled"); - isSellAllSoundEnabled = getBooleanValue("Options.Sell_Sound_Enabled"); - isSellAllBackpackItemsEnabled = getBooleanValue("Options.Sell_Prison_BackPack_Items"); - isSellAllMinesBackpacksPluginEnabled = getBooleanValue("Options.Sell_MinesBackPacks_Plugin_Backpack"); - isSellAllDelayEnabled = getBooleanValue("Options.Sell_Delay_Enabled"); - isSellAllSellPermissionEnabled = getBooleanValue("Options.Sell_Permission_Enabled"); - isSellAllItemTriggerEnabled = getBooleanValue("Options.ShiftAndRightClickSellAll.Enabled"); - isSellAllItemTriggerPermissionEnabled = getBooleanValue("Options.ShiftAndRightClickSellAll.PermissionEnabled"); - isSellAllGUIEnabled = getBooleanValue("Options.GUI_Enabled"); - isSellAllPlayerGUIEnabled = getBooleanValue("Options.Player_GUI_Enabled"); - isSellAllGUIPermissionEnabled = getBooleanValue("Options.GUI_Permission_Enabled"); - isSellAllPlayerGUIPermissionEnabled = getBooleanValue("Options.Player_GUI_Permission_Enabled"); - isSellAllMultiplierEnabled = getBooleanValue("Options.Multiplier_Enabled"); - isSellAllPermissionMultiplierOnlyHigherEnabled = getBooleanValue("Options.Multiplier_Permission_Only_Higher"); - isSellAllSignEnabled = getBooleanValue("Options.SellAll_Sign_Enabled"); - isSellAllSignNotifyEnabled = getBooleanValue("Options.SellAll_Sign_Notify"); - isSellAllSignPermissionToUseEnabled = getBooleanValue("Options.SellAll_Sign_Use_Permission_Enabled"); - isSellAllBySignOnlyEnabled = getBooleanValue("Options.SellAll_By_Sign_Only"); - isSellAllHandEnabled = getBooleanValue("Options.SellAll_Hand_Enabled"); - - isSellAllIgnoreCustomNames = getBooleanValue("Options.SellAll_ignoreCustomNames", false); - } - - private boolean getBooleanValue( String configName ) { - return getBooleanValue(configName, false); - } - private boolean getBooleanValue( String configName, Boolean defaultValue ) { - boolean results = (defaultValue == null ? false : defaultValue.booleanValue() ); - - if ( configName != null ) { - if ( sellAllConfig.isString(configName) ) { - String boolVal = sellAllConfig.getString(configName); - if ( boolVal != null ) { - // Boolean.parseBoolean() also supports yes and no so don't pretest for true/false. - try { - results = Boolean.parseBoolean(boolVal); - } catch (Exception e) { - // Not a boolean value, so ignore and let the "defaut" value stand - } - } - else { - // ignore since it's not a boolean value and let the "default" value stand - } - } - else if ( sellAllConfig.isBoolean(configName) ) { - results = sellAllConfig.getBoolean(configName, results); - } - else { - // Ignore since the config is not boolean or a String that "could" be a boolean - } - } - - return results; - } + /** * Loads sellAll blocks from SellAllConfig.yml * With XMaterials and double values (money). * - * @return HashMap XMaterial-Double. + * @return HashMap * */ - public HashMap initSellAllBlocks(){ + public HashMap initSellAllItems(){ - HashMap sellAllXMaterials = new HashMap<>(); + HashMap sellAllItems = new HashMap<>(); + +// HashMap sellAllXMaterials = new HashMap<>(); if (sellAllConfig.getConfigurationSection("Items") == null){ - return sellAllXMaterials; + return sellAllItems; } for (String key : sellAllConfig.getConfigurationSection("Items").getKeys(false)) { - String itemID = sellAllConfig.getString("Items." + key + ".ITEM_ID"); - - Optional iMatOptional = XMaterial.matchXMaterial(itemID); - XMaterial itemMaterial = iMatOptional.orElse(null); - - if (itemMaterial != null) { - String valueString = sellAllConfig.getString("Items." + key + ".ITEM_VALUE"); - if (valueString != null) { - try { - double value = Double.parseDouble(valueString); - sellAllXMaterials.put(itemMaterial, value); - } catch (NumberFormatException ignored) { - } - } + String itemName = key.trim().toUpperCase(); + + String itemID = sellAllConfig.getString("Items." + itemName + ".ITEM_ID"); + + PrisonBlock pBlock = Prison.get().getPlatform().getPrisonBlock(itemID); + + if ( pBlock != null ) { + String saleValueString = sellAllConfig.getString("Items." + itemName + ".ITEM_VALUE"); + if ( saleValueString != null ) { + + try { + double value = Double.parseDouble(saleValueString); + pBlock.setSalePrice( value ); + } catch (NumberFormatException ignored) { + } + } + + String purchaseValueString = sellAllConfig.getString("Items." + itemName + ".PURCHASE_PRICE"); + if ( purchaseValueString != null ) { + + try { + double value = Double.parseDouble(purchaseValueString); + pBlock.setPurchasePrice( value ); + } catch (NumberFormatException ignored) { + } + } + sellAllItems.put( pBlock.getBlockName().toLowerCase(), pBlock ); } + +// Optional iMatOptional = XMaterial.matchXMaterial(itemID); +// XMaterial itemMaterial = iMatOptional.orElse(null); + +// if (itemMaterial != null) { +// String valueString = sellAllConfig.getString("Items." + key.trim().toUpperCase() + ".ITEM_VALUE"); +// if (valueString != null) { +// try { +// double value = Double.parseDouble(valueString); +// sellAllXMaterials.put(itemMaterial, value); +// } catch (NumberFormatException ignored) { +// } +// } +// } } - return sellAllXMaterials; + return sellAllItems; } /** @@ -921,21 +1108,47 @@ public ArrayList initSellAllItemTrigger(){ * @return boolean. * */ public boolean addSellAllBlock(XMaterial xMaterial, double value){ + + PrisonBlock pBlockKey = Prison.get().getPlatform().getPrisonBlock( xMaterial.name() ); + if ( pBlockKey == null ) { + Output.get().logDebug( "sellall add: invalid block name (%s)", xMaterial.name()); + return false; + } + String key = pBlockKey.getBlockName().toLowerCase(); + + PrisonBlock pBlock = sellAllItems.get( key ); + + // If that is an invalid PrisonBlock, then exit + if ( pBlock != null ) { + Output.get().logDebug( "sellall add: block already exists (%s)", xMaterial.name()); + return false; + } + try { + + String itemName = pBlockKey.getBlockName().toUpperCase(); + File sellAllFile = new File(SpigotPrison.getInstance().getDataFolder() + "/SellAllConfig.yml"); FileConfiguration conf = YamlConfiguration.loadConfiguration(sellAllFile); - conf.set("Items." + xMaterial.name() + ".ITEM_ID", xMaterial.name()); - conf.set("Items." + xMaterial.name() + ".ITEM_VALUE", value); + conf.set("Items." + itemName + ".ITEM_ID", xMaterial.name()); + conf.set("Items." + itemName + ".ITEM_VALUE", value); if (getBooleanValue("Options.Sell_Per_Block_Permission_Enabled")) { - conf.set("Items." + xMaterial.name() + ".ITEM_PERMISSION", sellAllConfig.getString("Options.Sell_Per_Block_Permission") + xMaterial.name()); + String itemPerm = "Items." + itemName + ".ITEM_PERMISSION"; + conf.set( itemPerm, sellAllConfig.getString("Options.Sell_Per_Block_Permission") + xMaterial.name()); } conf.save(sellAllFile); + updateConfig(); + + pBlockKey.setSalePrice( value ); + sellAllItems.put( pBlockKey.getBlockName().toLowerCase(), pBlockKey ); + } catch (IOException e) { e.printStackTrace(); return false; } - updateConfig(); - sellAllBlocks.put(xMaterial, value); + + +// sellAllBlocks.put(xMaterial, value); return true; } @@ -1047,7 +1260,7 @@ public boolean addItemTrigger(XMaterial xMaterial){ // /** // * BUG: With Spigot versions less than 1.13 bukkit's Material will not work on all Materials since -// * varient data is stored in the ItemStack. SO must use the XMaterial version of this function. +// * variant data is stored in the ItemStack. SO must use the XMaterial version of this function. // * // * Add SellAll Item Trigger. // * @@ -1111,54 +1324,54 @@ public void addDelayedEarningAutoSellNotification(Player p, double value){ } } - private HashMap addInventoryToHashMap(HashMap xMaterialIntegerHashMap, Inventory inv) { - - List inventory = new ArrayList<>(); - - for (ItemStack itemStack : inv.getContents()){ - if (itemStack != null){ - inventory.add(itemStack); - } - } - - return addInventoryToHashMap( xMaterialIntegerHashMap, inventory ); - -// for (ItemStack itemStack : inv.getContents()){ +// private HashMap addInventoryToHashMap(HashMap xMaterialIntegerHashMap, Inventory inv) { +// +// List inventory = new ArrayList<>(); +// +// for (ItemStack itemStack : inv.getContents()){ // if (itemStack != null){ -// XMaterial xMaterial = getXMaterialOrLapis(itemStack); -// -// if ( xMaterial != null ) { -// -// if (xMaterialIntegerHashMap.containsKey(xMaterial)){ -// xMaterialIntegerHashMap.put(xMaterial, xMaterialIntegerHashMap.get(xMaterial) + itemStack.getAmount()); -// } -// else { -// xMaterialIntegerHashMap.put(xMaterial, itemStack.getAmount()); -// } -// } +// inventory.add(itemStack); // } -// } -// return xMaterialIntegerHashMap; - } +// } +// +// return addInventoryToHashMap( xMaterialIntegerHashMap, inventory ); +// +//// for (ItemStack itemStack : inv.getContents()){ +//// if (itemStack != null){ +//// XMaterial xMaterial = getXMaterialOrLapis(itemStack); +//// +//// if ( xMaterial != null ) { +//// +//// if (xMaterialIntegerHashMap.containsKey(xMaterial)){ +//// xMaterialIntegerHashMap.put(xMaterial, xMaterialIntegerHashMap.get(xMaterial) + itemStack.getAmount()); +//// } +//// else { +//// xMaterialIntegerHashMap.put(xMaterial, itemStack.getAmount()); +//// } +//// } +//// } +//// } +//// return xMaterialIntegerHashMap; +// } - private HashMap addInventoryToHashMap(HashMap xMaterialIntegerHashMap, List inv) { - for (ItemStack itemStack : inv){ - if (itemStack != null){ - XMaterial xMaterial = getXMaterialOrLapis(itemStack); - - if ( xMaterial != null ) { - - if (xMaterialIntegerHashMap.containsKey(xMaterial)){ - xMaterialIntegerHashMap.put(xMaterial, xMaterialIntegerHashMap.get(xMaterial) + itemStack.getAmount()); - } - else { - xMaterialIntegerHashMap.put(xMaterial, itemStack.getAmount()); - } - } - } - } - return xMaterialIntegerHashMap; - } +// private HashMap addInventoryToHashMap(HashMap xMaterialIntegerHashMap, List inv) { +// for (ItemStack itemStack : inv){ +// if (itemStack != null){ +// XMaterial xMaterial = getXMaterialOrLapis(itemStack); +// +// if ( xMaterial != null ) { +// +// if (xMaterialIntegerHashMap.containsKey(xMaterial)){ +// xMaterialIntegerHashMap.put(xMaterial, xMaterialIntegerHashMap.get(xMaterial) + itemStack.getAmount()); +// } +// else { +// xMaterialIntegerHashMap.put(xMaterial, itemStack.getAmount()); +// } +// } +// } +// } +// return xMaterialIntegerHashMap; +// } /** * Check if Player meets requirements to use SellAll. @@ -1211,26 +1424,54 @@ public boolean canPlayerSell(Player p, boolean isUsingSign){ * */ public boolean editPrice(XMaterial xMaterial, double value){ + PrisonBlock pBlockKey = Prison.get().getPlatform().getPrisonBlock( xMaterial.name() ); + String key = pBlockKey.getBlockName().toLowerCase(); + + PrisonBlock pBlock = sellAllItems.get( key ); + // Do not allow an edit price if the material does not exist, or if the value has not changed: - if (!sellAllBlocks.containsKey(xMaterial) && sellAllBlocks.get(xMaterial) != value ){ + if ( pBlock == null ){ + + Output.get().logDebug( "sellall edit: item does not exist in shop so it cannot be edited (%s)", pBlockKey.getBlockName()); return false; } + if ( pBlock.getSalePrice() == value ){ + DecimalFormat dFmt = new DecimalFormat("#,##0.00"); + Output.get().logDebug( "sellall edit: No change in price (%s:%s)", + pBlockKey.getBlockName(), dFmt.format(value) ); + return false; + } + + pBlock.setSalePrice( value ); try { File sellAllFile = new File(SpigotPrison.getInstance().getDataFolder() + "/SellAllConfig.yml"); FileConfiguration conf = YamlConfiguration.loadConfiguration(sellAllFile); - conf.set("Items." + xMaterial.name() + ".ITEM_ID", xMaterial.name()); - conf.set("Items." + xMaterial.name() + ".ITEM_VALUE", value); + + String itemName = key.toUpperCase(); + conf.set("Items." + itemName + ".ITEM_ID", key ); + conf.set("Items." + itemName + ".ITEM_VALUE", value); + + if ( pBlock.getPurchasePrice() != null ) { + + conf.set("Items." + itemName + ".PURCHASE_PRICE", pBlock.getPurchasePrice().doubleValue() ); + } + if (getBooleanValue("Options.Sell_Per_Block_Permission_Enabled")) { - conf.set("Items." + xMaterial + ".ITEM_PERMISSION", sellAllConfig.getString("Options.Sell_Per_Block_Permission") + xMaterial.name()); + conf.set("Items." + itemName + ".ITEM_PERMISSION", sellAllConfig.getString("Options.Sell_Per_Block_Permission") + itemName ); } conf.save(sellAllFile); + + // Update only if successful + updateConfig(); } catch (IOException e) { e.printStackTrace(); return false; } - updateConfig(); - sellAllBlocks.put(xMaterial, value); + + // pBlock is still in the sellAllItems collection so no need to readd it +// sellAllBlocks.put(xMaterial, value); + return true; } @@ -1279,21 +1520,29 @@ public boolean editPrestigeMultiplier(String prestigeName, double multiplier) { * */ public boolean removeSellAllBlock(XMaterial xMaterial){ - if (!sellAllBlocks.containsKey(xMaterial)){ + PrisonBlock pBlockKey = Prison.get().getPlatform().getPrisonBlock( xMaterial.name() ); + String key = pBlockKey.getBlockName().toLowerCase(); + + PrisonBlock pBlock = sellAllItems.get( key ); + + if ( pBlock == null ){ return false; } try { File sellAllFile = new File(SpigotPrison.getInstance().getDataFolder() + "/SellAllConfig.yml"); FileConfiguration conf = YamlConfiguration.loadConfiguration(sellAllFile); - conf.set("Items." + xMaterial.name(), null); + conf.set("Items." + pBlock.getBlockName().toUpperCase(), null); conf.save(sellAllFile); + + updateConfig(); } catch (IOException e) { e.printStackTrace(); return false; } - updateConfig(); - sellAllBlocks.remove(xMaterial); + + sellAllItems.remove( key ); +// sellAllBlocks.remove(xMaterial); return true; } @@ -1387,197 +1636,254 @@ public boolean removeItemTrigger(XMaterial xMaterial){ // return removeItemTrigger(XMaterial.matchXMaterial(material)); // } - /** - * Remove Sellable Blocks from HashMap of XMaterial-Integer given as a parameter. - * NOTE: If there aren't blocks in the SellAll shop, nothing will change. - * NOTE: This method will remove blocks from the HashMap, but it WON'T return the value of money, for that please use - * the getSellAllSellMoney method. - * - * @param p - Player. - * @param xMaterialIntegerHashMap - HashMap of XMaterial-Integer (Blocks of origin). - * - * - * @return HashMap - XMaterial-Integer. - * */ - public HashMap removeSellableItems(Player p, HashMap xMaterialIntegerHashMap){ - - if (sellAllBlocks.isEmpty()){ - return xMaterialIntegerHashMap; - } - - /* Not necessary now, as this only removes what's sellable, this should be checked in another place before. - if (isPlayerInDisabledWorld(p)){ - return xMaterialIntegerHashMap; - } - */ - - for (HashMap.Entry xMaterialIntegerEntry : xMaterialIntegerHashMap.entrySet()){ - if (sellAllBlocks.containsKey(xMaterialIntegerEntry.getKey())){ - // This is stupid but right now I'm too confused, sorry. - if (isPerBlockPermissionEnabled && !p.hasPermission(permissionPrefixBlocks + xMaterialIntegerEntry.getKey().name())){ - // Nothing will happen. - } else { - xMaterialIntegerHashMap.remove(xMaterialIntegerEntry.getKey()); - } - } - } - - return xMaterialIntegerHashMap; - } - - /** - * Remove Sellable Blocks from ArrayList of ItemStacks given as a parameter. - * NOTE: If there aren't blocks in the SellAll shop, nothing will change. - * NOTE: This method will remove blocks from the HashMap, but it WON'T return the value of money, for that please use - * the getSellAllSellMoney method. - * - * @param p - Player. - * @param itemStacks - ItemStacks. - * - * @return ArrayList - ItemStacks. - * */ - public ArrayList removeSellableItems(Player p, ArrayList itemStacks){ - - if (sellAllBlocks.isEmpty()){ - return itemStacks; - } - - HashMap xMaterialIntegerHashMap = getXMaterialsHashMapFromArrayList(itemStacks); - - xMaterialIntegerHashMap = removeSellableItems(p, xMaterialIntegerHashMap); - - ArrayList newItemStacks = new ArrayList<>(); - for (HashMap.Entry xMaterialIntegerEntry : xMaterialIntegerHashMap.entrySet()){ - - // WARNING: Cannot convert XMaterial to a Material then ItemStack or it will fail on variants - // for spigot versions less than 1.13: - - ItemStack iStack = xMaterialIntegerEntry.getKey().parseItem(); - if ( iStack != null ) { - iStack.setAmount( xMaterialIntegerEntry.getValue() ); - newItemStacks.add( iStack ); - } - -// Material material = xMaterialIntegerEntry.getKey().parseMaterial(); -// if (material != null) { -// newItemStacks.add(new ItemStack(material, xMaterialIntegerEntry.getValue())); +// /** +// * Remove Sellable Blocks from HashMap of XMaterial-Integer given as a parameter. +// * NOTE: If there aren't blocks in the SellAll shop, nothing will change. +// * NOTE: This method will remove blocks from the HashMap, but it WON'T return the value of money, for that please use +// * the getSellAllSellMoney method. +// * +// * @param p - Player. +// * @param xMaterialIntegerHashMap - HashMap of XMaterial-Integer (Blocks of origin). +// * +// * +// * @return HashMap - XMaterial-Integer. +// * */ +// public HashMap removeSellableItems(Player p, HashMap xMaterialIntegerHashMap){ +// +// if (sellAllItems.isEmpty()){ +// return xMaterialIntegerHashMap; +// } +// +// /* Not necessary now, as this only removes what's sellable, this should be checked in another place before. +// if (isPlayerInDisabledWorld(p)){ +// return xMaterialIntegerHashMap; +// } +// */ +// +// for (HashMap.Entry xMaterialIntegerEntry : xMaterialIntegerHashMap.entrySet()){ +// +// XMaterial xMaterial = xMaterialIntegerEntry.getKey(); +// PrisonBlock pBlockKey = Prison.get().getPlatform().getPrisonBlock( xMaterial.name() ); +// String key = pBlockKey.getBlockName(); +// +// PrisonBlock pBlock = sellAllItems.get( key ); +// +// if ( pBlock != null ){ +// // This is stupid but right now I'm too confused, sorry. +// if (isPerBlockPermissionEnabled && !p.hasPermission(permissionPrefixBlocks + pBlock.getBlockName().toUpperCase() )){ +// // Nothing will happen. +// } else { +// xMaterialIntegerHashMap.remove( xMaterial ); +// } // } - } +// } +// +// return xMaterialIntegerHashMap; +// } - return newItemStacks; - } - - /** - * Remove Sellable blocks from an Inventory of a Player. - * - * Return an Inventory with the unsold items. - * - * @param p - Player. - * @param inv - Inventory. - * - * @return inv - Inventory. - * */ - public Inventory removeSellableItems(Player p, Inventory inv){ - if (sellAllBlocks.isEmpty()){ - return inv; - } - - SpigotCompatibility.getInstance().getItemInOffHand( p ); - - List removeable = new ArrayList<>(); - - for (ItemStack itemStack : inv.getContents()){ - if (itemStack != null){ - try { - XMaterial xMaterial = getXMaterialOrLapis(itemStack); - - if ( xMaterial != null && sellAllBlocks.containsKey(xMaterial)) { - if (isPerBlockPermissionEnabled && !p.hasPermission(permissionPrefixBlocks + xMaterial.name())) { - // Nothing will change. - } else { - removeable.add( itemStack ); -// inv.remove(itemStack); - } - } - } catch (IllegalArgumentException ignored){} - } - } - - for ( ItemStack remove : removeable ) - { - inv.remove(remove); - } - - return inv; - } +// /** +// * Remove Sellable Blocks from ArrayList of ItemStacks given as a parameter. +// * NOTE: If there aren't blocks in the SellAll shop, nothing will change. +// * NOTE: This method will remove blocks from the HashMap, but it WON'T return the value of money, for that please use +// * the getSellAllSellMoney method. +// * +// * @param p - Player. +// * @param itemStacks - ItemStacks. +// * +// * @return ArrayList - ItemStacks. +// * */ +// private ArrayList removeSellableItems(Player p, ArrayList itemStacks){ +// +// if (sellAllItems.isEmpty()){ +// return itemStacks; +// } +// +// HashMap xMaterialIntegerHashMap = getXMaterialsHashMapFromArrayList(itemStacks); +// +// xMaterialIntegerHashMap = removeSellableItems(p, xMaterialIntegerHashMap); +// +// ArrayList newItemStacks = new ArrayList<>(); +// for (HashMap.Entry xMaterialIntegerEntry : xMaterialIntegerHashMap.entrySet()){ +// +// // WARNING: Cannot convert XMaterial to a Material then ItemStack or it will fail on variants +// // for spigot versions less than 1.13: +// +// ItemStack iStack = xMaterialIntegerEntry.getKey().parseItem(); +// if ( iStack != null ) { +// iStack.setAmount( xMaterialIntegerEntry.getValue() ); +// newItemStacks.add( iStack ); +// } +// +//// Material material = xMaterialIntegerEntry.getKey().parseMaterial(); +//// if (material != null) { +//// newItemStacks.add(new ItemStack(material, xMaterialIntegerEntry.getValue())); +//// } +// } +// +// return newItemStacks; +// } - public void removeSellableItemsInOffHand(Player p){ - - - ItemStack itemStack = SpigotCompatibility.getInstance().getItemInOffHand( p ); - - if ( itemStack != null ) { - - if (itemStack != null){ - try { - XMaterial xMaterial = getXMaterialOrLapis(itemStack); - - if ( xMaterial != null && sellAllBlocks.containsKey(xMaterial)) { - if (isPerBlockPermissionEnabled && !p.hasPermission(permissionPrefixBlocks + xMaterial.name())) { - // Nothing will change. - } - else { - - SpigotPlayerInventory spInventory = new SpigotPlayerInventory( p.getInventory() ) ; - SpigotItemStack sItemStack = new SpigotItemStack( new ItemStack( Material.AIR ) ); - - SpigotCompatibility.getInstance().setItemStackInOffHand( spInventory, sItemStack ); - - } - } - } catch (IllegalArgumentException ignored){} - } - } - +// /** +// * Remove Sellable blocks from an Inventory of a Player. +// * +// * Return an Inventory with the unsold items. +// * +// * @param p - Player. +// * @param inv - Inventory. +// * +// * @return inv - Inventory. +// * */ +// private Inventory removeSellableItems(Player p, Inventory inv){ +// if (sellAllItems.isEmpty()){ +// return inv; +// } +// +// // ?? why? +//// SpigotCompatibility.getInstance().getItemInOffHand( p ); +// +// List removeable = new ArrayList<>(); +// +// SpigotInventory sInv = new SpigotInventory( inv ); +// +// for (tech.mcprison.prison.internal.ItemStack itemStack : sInv.getItems()) { +// if (itemStack != null){ +// try { +// PrisonBlock pBlock = itemStack.getMaterial(); +// +// +//// XMaterial xMaterial = getXMaterialOrLapis(itemStack); +// +// if ( pBlock != null && sellAllItems.containsKey( pBlock.getBlockName() )) { +// if (isPerBlockPermissionEnabled && !p.hasPermission(permissionPrefixBlocks + pBlock.getBlockName().toUpperCase() )) { +// // Nothing will change. +// } else { +// removeable.add( ((SpigotItemStack) itemStack).getBukkitStack() ); +//// inv.remove(itemStack); +// } +// } +// } catch (IllegalArgumentException ignored){} +// } +// } +// +//// for (ItemStack itemStack : inv.getContents()){ +//// if (itemStack != null){ +//// try { +//// PrisonBlock +//// +//// +//// XMaterial xMaterial = getXMaterialOrLapis(itemStack); +//// +//// if ( xMaterial != null && sellAllBlocks.containsKey(xMaterial)) { +//// if (isPerBlockPermissionEnabled && !p.hasPermission(permissionPrefixBlocks + xMaterial.name())) { +//// // Nothing will change. +//// } else { +//// removeable.add( itemStack ); +////// inv.remove(itemStack); +//// } +//// } +//// } catch (IllegalArgumentException ignored){} +//// } +//// } +// +// for ( ItemStack remove : removeable ) +// { +// inv.remove(remove); +// } +// +// return inv; +// } - } +// private void removeSellableItemsInOffHand(Player p){ +// +// +// +// SpigotItemStack sItemStack = SpigotCompatibility.getInstance().getPrisonItemInOffHand( p ); +// +// if ( sItemStack != null ) { +// +// PrisonBlock pBlock = sItemStack.getMaterial(); +// +// if ( pBlock != null && sellAllItems.containsKey( pBlock.getBlockName() )) { +// if (isPerBlockPermissionEnabled && !p.hasPermission(permissionPrefixBlocks + pBlock.getBlockName().toUpperCase() )) { +// // Nothing will change. +// } else { +// +// SpigotPlayer sPlayer = new SpigotPlayer( p ); +// SpigotPlayerInventory spInventory = (SpigotPlayerInventory) sPlayer.getInventory(); +// +// SpigotItemStack sItemStackAir = (SpigotItemStack) PrisonBlock.AIR.getItemStack( 1 ); +// +// SpigotCompatibility.getInstance().setItemStackInOffHand( spInventory, sItemStackAir ); +// } +// } +// } +// +// +// +//// ItemStack itemStack = SpigotCompatibility.getInstance().getItemInOffHand( p ); +//// +//// if ( itemStack != null ) { +//// +//// if (itemStack != null){ +//// try { +//// XMaterial xMaterial = getXMaterialOrLapis(itemStack); +//// +//// if ( xMaterial != null && sellAllBlocks.containsKey(xMaterial)) { +//// if (isPerBlockPermissionEnabled && !p.hasPermission(permissionPrefixBlocks + xMaterial.name())) { +//// // Nothing will change. +//// } +//// else { +//// +//// SpigotPlayerInventory spInventory = new SpigotPlayerInventory( p.getInventory() ) ; +//// SpigotItemStack sItemStack = new SpigotItemStack( new ItemStack( Material.AIR ) ); +//// +//// SpigotCompatibility.getInstance().setItemStackInOffHand( spInventory, sItemStack ); +//// +//// } +//// } +//// } catch (IllegalArgumentException ignored){} +//// } +//// } +// +// +// } - /** - * Remove Sellable blocks from all Player inventories directly hooked. - * - * @param p - Player. - * */ - public void removeSellableItems(Player p){ - - if (sellAllBlocks.isEmpty()){ - return; - } - - if (isSellAllBackpackItemsEnabled && getBoolean(SpigotPrison.getInstance().getConfig().getString("backpacks"))){ - BackpacksUtil backpacksUtil = BackpacksUtil.get(); - if (backpacksUtil.isMultipleBackpacksEnabled()){ - for (String id : backpacksUtil.getBackpacksIDs(p)){ - backpacksUtil.setInventory(p, removeSellableItems(p, backpacksUtil.getBackpack(p, id)), id); - } - } else { - String id = null; - backpacksUtil.setInventory(p, removeSellableItems(p, backpacksUtil.getBackpack(p, id)), id); - } - } - - if (isSellAllMinesBackpacksPluginEnabled && IntegrationMinepacksPlugin.getInstance().isEnabled()){ - Backpack backpack = IntegrationMinepacksPlugin.getInstance().getMinepacks().getBackpackCachedOnly(p); - if (backpack != null) { - removeSellableItems(p, backpack.getInventory()); - backpack.setChanged(); - backpack.save(); - } - } - - removeSellableItems(p, p.getInventory()); - - removeSellableItemsInOffHand( p ); - } +// /** +// * Remove Sellable blocks from all Player inventories directly hooked. +// * +// * @param p - Player. +// * */ +// private void removeSellableItems(Player p){ +// +// if (sellAllItems.isEmpty()){ +// return; +// } +// +// if (isSellAllBackpackItemsEnabled && getBoolean(SpigotPrison.getInstance().getConfig().getString("backpacks"))){ +// BackpacksUtil backpacksUtil = BackpacksUtil.get(); +// if (backpacksUtil.isMultipleBackpacksEnabled()){ +// for (String id : backpacksUtil.getBackpacksIDs(p)){ +// backpacksUtil.setInventory(p, removeSellableItems(p, backpacksUtil.getBackpack(p, id)), id); +// } +// } else { +// String id = null; +// backpacksUtil.setInventory(p, removeSellableItems(p, backpacksUtil.getBackpack(p, id)), id); +// } +// } +// +// if (isSellAllMinesBackpacksPluginEnabled && IntegrationMinepacksPlugin.getInstance().isEnabled()){ +// Backpack backpack = IntegrationMinepacksPlugin.getInstance().getMinepacks().getBackpackCachedOnly(p); +// if (backpack != null) { +// removeSellableItems(p, backpack.getInventory()); +// backpack.setChanged(); +// backpack.save(); +// } +// } +// +// removeSellableItems(p, p.getInventory()); +// +// removeSellableItemsInOffHand( p ); +// } /** * Remove Player from delay. @@ -1833,13 +2139,20 @@ public boolean setDelay(int delay){ * * @return boolean If successful * */ - public boolean sellAllSell(Player p, boolean isUsingSign, boolean completelySilent, boolean notifyPlayerEarned, - boolean notifyPlayerDelay, boolean notifyPlayerEarningDelay, boolean playSoundOnSellAll){ + public boolean sellAllSell(Player p, + boolean isUsingSign, boolean completelySilent, + boolean notifyPlayerEarned, + boolean notifyPlayerDelay, boolean notifyPlayerEarningDelay, + boolean playSoundOnSellAll) { return sellAllSell( p, isUsingSign, completelySilent, notifyPlayerEarned, notifyPlayerDelay, notifyPlayerEarningDelay, playSoundOnSellAll, null ); } - public boolean sellAllSell(Player p, boolean isUsingSign, boolean completelySilent, boolean notifyPlayerEarned, - boolean notifyPlayerDelay, boolean notifyPlayerEarningDelay, boolean playSoundOnSellAll, List amounts ){ + + public boolean sellAllSell(Player p, + boolean isUsingSign, boolean completelySilent, + boolean notifyPlayerEarned, + boolean notifyPlayerDelay, boolean notifyPlayerEarningDelay, + boolean playSoundOnSellAll, List amounts ){ if (!isUsingSign && isSellAllSignEnabled && isSellAllBySignOnlyEnabled && !p.hasPermission(permissionBypassSign)){ if (!completelySilent) { @@ -1859,7 +2172,7 @@ public boolean sellAllSell(Player p, boolean isUsingSign, boolean completelySile return false; } - if (sellAllBlocks.isEmpty()){ + if (sellAllItems.isEmpty()){ if (!completelySilent){ sellallShopIsEmptyMsg( new SpigotCommandSender(p) ); @@ -1867,9 +2180,24 @@ public boolean sellAllSell(Player p, boolean isUsingSign, boolean completelySile } return false; } + + + + double money = 0; + double multiplier = getPlayerMultiplier(p); + + List soldItems = sellPlayerItems(p); + + for (SellAllData soldItem : soldItems) { + money += soldItem.getTransactionAmount(); + } + + SellAllData.debugItemsSold( soldItems, new SpigotPlayer( p ), multiplier ); + + //TODO inventory access: getHashMapOfPlayerInventories() && removeSellableItems(p, p.getInventory()); - double money = getSellMoney(p); +// double money = getSellMoney(p); if (money != 0){ if ( amounts != null ) { @@ -1883,7 +2211,7 @@ public boolean sellAllSell(Player p, boolean isUsingSign, boolean completelySile //TODO inventory access: getHashMapOfPlayerInventories() && removeSellableItems(p, p.getInventory()); - removeSellableItems(p); + //removeSellableItems(p); SpigotPlayer sPlayer = new SpigotPlayer(p); @@ -1941,8 +2269,9 @@ public boolean sellAllSell(Player p, boolean isUsingSign, boolean completelySile } } - - /** + + + /** *

This function enables the selling of just one ItemStack and can be used outside of * the player's inventory, such as processing the drops of tens of thousands of blocks * worth of drops. This would be much faster than processing the player's inventory. @@ -1967,7 +2296,24 @@ public double sellAllSell(Player p, SpigotItemStack itemStack, // long tPoint4 = tPoint1; // long tPoint5 = tPoint1; - double money = getSellMoney(p, itemStack); + + double money = 0; + double multiplier = getPlayerMultiplier(p); + + List soldItems = new ArrayList<>(); + + SellAllData sad = sellItemStack( itemStack, multiplier ); + if ( sad != null ) { + soldItems.add(sad); + } + + for (SellAllData soldItem : soldItems) { + money += soldItem.getTransactionAmount(); + } + + SellAllData.debugItemsSold(soldItems, new SpigotPlayer(p), multiplier); + +// double money = getSellMoney(p, itemStack); // tPoint2 = System.nanoTime(); @@ -2062,7 +2408,11 @@ else if (notifyPlayerEarned){ * * @return boolean. * */ - public ArrayList sellAllSell(Player p, ArrayList itemStacks, boolean isUsingSign, boolean completelySilent, boolean notifyPlayerEarned, boolean notifyPlayerDelay, boolean notifyPlayerEarningDelay, boolean playSoundOnSellAll, boolean sellInputArrayListOnly){ + public ArrayList sellAllSell(Player p, ArrayList itemStacks, + boolean isUsingSign, boolean completelySilent, + boolean notifyPlayerEarned, boolean notifyPlayerDelay, + boolean notifyPlayerEarningDelay, boolean playSoundOnSellAll, + boolean sellInputArrayListOnly){ if (!isUsingSign && isSellAllSignEnabled && isSellAllBySignOnlyEnabled && !p.hasPermission(permissionBypassSign)){ if (!completelySilent) { @@ -2081,7 +2431,7 @@ public ArrayList sellAllSell(Player p, ArrayList itemStack return itemStacks; } - if (sellAllBlocks.isEmpty()){ + if (sellAllItems.isEmpty()){ if (!completelySilent){ sellallShopIsEmptyMsg( new SpigotCommandSender(p) ); @@ -2090,17 +2440,58 @@ public ArrayList sellAllSell(Player p, ArrayList itemStack return itemStacks; } - double arrayListMoney = getSellMoney(p, itemStacks); - if (arrayListMoney != 0.00){ - itemStacks = removeSellableItems(p, itemStacks); + + double money = 0; + double multiplier = getPlayerMultiplier(p); + + List soldItems = new ArrayList<>(); + + ArrayList itemsNotSold = new ArrayList<>(); + + for (ItemStack itemStack : itemStacks ) { + + SellAllData sad = sellItemStack( new SpigotItemStack( itemStack ), multiplier ); + if ( sad != null ) { + soldItems.add(sad); + } + else { + itemsNotSold.add( itemStack ); + } + } + + // "return" all items not sold: + itemStacks.clear(); + itemStacks.addAll( itemsNotSold ); + + + // Sell the player's inventory if requested + if ( !sellInputArrayListOnly ) { + soldItems.addAll( sellPlayerItems(p) ); } + + for (SellAllData soldItem : soldItems) { + money += soldItem.getTransactionAmount(); + } - double money; - if (sellInputArrayListOnly){ - money = arrayListMoney; - } else { - money = getSellMoney(p) + arrayListMoney; - } + + SellAllData.debugItemsSold( soldItems, new SpigotPlayer( p ), multiplier ); + + + // Sell only the itemStacks and then remove the ones that were sold: +// double arrayListMoney = getSellMoney(p, itemStacks); +// if (arrayListMoney != 0.00){ +// itemStacks = removeSellableItems(p, itemStacks); +// } + +// double money; +// +// // If to include the player's inventory, then add that too: +// if (sellInputArrayListOnly){ +// money = arrayListMoney; +// } else { +// // Add the players inventory +// money = getSellMoney(p) + arrayListMoney; +// } if (money != 0){ @@ -2108,9 +2499,9 @@ public ArrayList sellAllSell(Player p, ArrayList itemStack RankPlayer rankPlayer = PrisonRanks.getInstance().getPlayerManager().getPlayer(sPlayer.getUUID(), sPlayer.getName()); if (sellAllCurrency != null && sellAllCurrency.equalsIgnoreCase("default")) sellAllCurrency = null; - if (!sellInputArrayListOnly) { - removeSellableItems(p); - } +// if (!sellInputArrayListOnly) { +// removeSellableItems(p); +// } rankPlayer.addBalance(sellAllCurrency, money); if (isSellAllDelayEnabled){ @@ -2153,7 +2544,9 @@ public ArrayList sellAllSell(Player p, ArrayList itemStack return itemStacks; } - /** + + + /** * Open SellAll GUI to the specified Player. * NOTE: SellAll GUI must be enabled from the config or nothing will happen. * NOTE #2: A Player if admin will open another GUI if meets requirements, if not it will try to check From 28aff3a625cd83cc787d6ac5692c95657da4a3e4 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Thu, 13 Jul 2023 00:31:57 -0400 Subject: [PATCH 013/151] New sellall features: 'sellall valueof' calculates the value of everything in the player's inventory that can be sold. '/sellall valueofHand' calculates what is held in the player's hand. --- docs/changelog_v3.3.x.md | 9 ++ .../commands/PrisonSpigotSellAllCommands.java | 122 ++++++++++++++++++ 2 files changed, 131 insertions(+) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index cb0f718bf..e237c9747 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -17,6 +17,15 @@ These change logs represent the work that has been going on within prison. # 3.3.0-alpha.15 2023-07-13 +* **New sellall features: 'sellall valueof' calculates the value of everything in the player's inventory that can be sold. '/sellall valueofHand' calculates what is held in the player's hand.** + + +* **Major rewrites to sellall to utilize more of Prison's internal classes and to get away from XMaterial since it cannot handle custom blocks.** +A lot of sellall code has been eliminated, but no loss in functionality. Actually new functions and enhancements have been added. +Eliminated the two step process of selling... where it first calculated the values, then after the fact, would try to remove the items with no "validation" that the items removed were the items that calculated the sales amount. +Sellall commands: moved the '/sellall trigger add' and '/sellall trigger remove' to under the '/sell set' section since they were hidden because '/sellall trigger' was a command and many did not realize they have to use the 'help' keyword to show the others. + + * **Updated Prison's PlayerInventory to include 'contents' and 'extraContents' to match the bukkit PlayerInventory object.** Within the SpigotPlayerInventory class, overrode the behavior of removeItem to ensure that obscure inventory locations are being removed, since there was a bug where you can get all inventory items, then remove them, and they would not remove all occurrences of the items stacks that were initially returned, such as when someone is wearing an item as a hat, or holding something in one of their hands. diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/commands/PrisonSpigotSellAllCommands.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/commands/PrisonSpigotSellAllCommands.java index b8b5dd928..c8a3b9b66 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/commands/PrisonSpigotSellAllCommands.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/commands/PrisonSpigotSellAllCommands.java @@ -392,6 +392,128 @@ public void sellAllSell(Player p){ } + + + @Command(identifier = "sellall valueof", + description = "SellAll valueof command will report the total value of the player's inventory " + + "without selling anything.", onlyPlayers = false) + public void sellAllValueOfCommand(CommandSender sender, + @Arg(name = "player", def = "", description = "An online player name to get the value of their inventory - " + + "Only console or prison commands can include this parameter") String playerName + ){ + + if (!isEnabled()) return; + + Player p = getSpigotPlayer(sender); + + + boolean isOp = sender.isOp(); + + tech.mcprison.prison.internal.Player sPlayerAlt = getOnlinePlayer( sender, playerName ); +// if ( sPlayerAlt == null ){ +// // If sPlayerAlt is null then the value in playerName is really intended for notification: +// notification = playerName; +// } + + if ( isOp && !sender.isPlayer() && sPlayerAlt != null ) { + // Only if OP and a valid player name was provided, then OP is trying to run this + // for another player + + if ( !sPlayerAlt.isOnline() ) { + sender.sendMessage( "Player is not online." ); + return; + } + + // Set the active player to who OP specified: + p = ((SpigotPlayer) sPlayerAlt).getWrapper(); + } + + + else if (p == null){ + + if ( getPlayer( sender, playerName ) != null ) { + + Output.get().sendInfo(sender, "&cSorry but the specified player must be online " + + "[/sellall valueof %s]", playerName ); + } + else { + + Output.get().sendInfo(sender, "&cSorry but you can't use that from the console!"); + } + + + return; + } + + + SellAllUtil sellAllUtil = SellAllUtil.get(); + if (sellAllUtil == null){ + return; + } + +// if (sellAllUtil.isPlayerInDisabledWorld(p)) return; + + if (sellAllUtil.isSellAllSellPermissionEnabled){ + String permission = sellAllUtil.permissionSellAllSell; + if (permission == null || !p.hasPermission(permission)){ + Output.get().sendWarn(new SpigotPlayer(p), messages.getString(MessagesConfig.StringID.spigot_message_missing_permission) + " [" + permission + "]"); + return; + } + } + + SpigotPlayer sPlayer = new SpigotPlayer( p ); + + String report = sellAllUtil.getPlayerInventoryValueReport( sPlayer ); + + + sender.sendMessage(report); + + PlayerAutoRankupTask.autoSubmitPlayerRankupTask( sPlayer, null ); + } + + @Command(identifier = "sellall valueofHand", + description = "Get the value of what is in your hand if sellable.", + onlyPlayers = true) + public void sellAllValueOfHandCommand(CommandSender sender){ + + if (!isEnabled()) return; + + SellAllUtil sellAllUtil = SellAllUtil.get(); + + if (sellAllUtil == null){ + return; + } + + if (!sellAllUtil.isSellAllHandEnabled){ + Output.get().sendWarn(sender, "The command /sellall valueofHand is disabled from the config! (SellAllHandEnabled)"); + return; + } + + Player p = getSpigotPlayer(sender); + + if (p == null){ + Output.get().sendInfo(sender, "&cSorry but you can't use that from the console!"); + return; + } + +// if (sellAllUtil.isPlayerInDisabledWorld(p)) return; + + if (sellAllUtil.isSellAllSellPermissionEnabled){ + String permission = sellAllUtil.permissionSellAllSell; + if (permission == null || !p.hasPermission(permission)){ + Output.get().sendWarn(new SpigotPlayer(p), messages.getString(MessagesConfig.StringID.spigot_message_missing_permission) + " [" + permission + "]"); + return; + } + } + + + String report = sellAllUtil.getItemStackValueReport( + new SpigotPlayer(p), new SpigotItemStack( compat.getItemInMainHand(p)) ); + + sender.sendMessage(report); + } + + @Command(identifier = "sellall delaysell", description = "Like SellAll Sell command but this will be delayed for some " + "seconds and if sellall sell commands are triggered during this delay, " + From 6f18d2fb191516f1c72ddabdddbdde48cd8909a0 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Thu, 13 Jul 2023 04:40:35 -0400 Subject: [PATCH 014/151] Sellall: Expanded the functionality of the SellAllData obejcts to indicate if the items were sold. --- docs/changelog_v3.3.x.md | 3 ++ .../prison/spigot/sellall/SellAllData.java | 38 +++++++++++++------ .../prison/spigot/sellall/SellAllUtil.java | 3 ++ 3 files changed, 32 insertions(+), 12 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index e237c9747..352a96cf8 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -17,6 +17,9 @@ These change logs represent the work that has been going on within prison. # 3.3.0-alpha.15 2023-07-13 +* **Sellall: Expanded the functionality of the SellAllData obejcts to indicate if the items were sold.** + + * **New sellall features: 'sellall valueof' calculates the value of everything in the player's inventory that can be sold. '/sellall valueofHand' calculates what is held in the player's hand.** diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/sellall/SellAllData.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/sellall/SellAllData.java index 4c639edc4..cca21122a 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/sellall/SellAllData.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/sellall/SellAllData.java @@ -20,10 +20,13 @@ public class SellAllData { private PrisonBlock prisonBlock; private int quantity; private double transactionAmount; + private boolean itemsSold; public SellAllData( PrisonBlock pBlock, int quantity, double transactionAmount ) { super(); + this.itemsSold = false; + this.prisonBlock = pBlock; this.quantity = quantity; this.transactionAmount = transactionAmount; @@ -39,6 +42,10 @@ public String toString() { .append( ":" ) .append( dFmt.format(getTransactionAmount()) ); + if ( isItemsSold() ) { + sb.append( ":SOLD" ); + } + return sb.toString(); } @@ -74,18 +81,18 @@ public static String itemsSoldReport( List soldItems, SpigotPlayer DecimalFormat iFmt = new DecimalFormat( "#,##0" ); sb.append( "Transaction log: " ) - .append( sPlayer.getName() ) - .append( " multiplier: " ) - .append( dFmt.format(multiplier) ) - .append( " ItemStacks: " ) - .append( soldItems.size() ) - .append( " ItemCount: " ) - .append( iFmt.format(itemCount) ) - .append( " TotalAmount: " ) - .append( dFmt.format( totalAmount )) - .append( " [" ) - .append( sbItems ) - .append("]"); + .append( sPlayer.getName() ) + .append( " multiplier: " ) + .append( dFmt.format(multiplier) ) + .append( " ItemStacks: " ) + .append( soldItems.size() ) + .append( " ItemCount: " ) + .append( iFmt.format(itemCount) ) + .append( " TotalAmount: " ) + .append( dFmt.format( totalAmount )) + .append( " [" ) + .append( sbItems ) + .append("]"); return sb.toString(); } @@ -110,5 +117,12 @@ public double getTransactionAmount() { public void setTransactionAmount(double transactionAmount) { this.transactionAmount = transactionAmount; } + + public boolean isItemsSold() { + return itemsSold; + } + public void setItemsSold(boolean itemsSold) { + this.itemsSold = itemsSold; + } } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/sellall/SellAllUtil.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/sellall/SellAllUtil.java index 5dd5c09b2..69c1188bc 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/sellall/SellAllUtil.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/sellall/SellAllUtil.java @@ -659,6 +659,9 @@ private List sellInventoryItems( tech.mcprison.prison.internal.inve SellAllData sad = sellItemStack( (SpigotItemStack)inv, multiplier ); if ( sad != null ) { + + sad.setItemsSold( true ); + soldItems.add(sad); removable.add(inv); From bb004e1c966a9230c83a788d7bcb425aa8ab1b2c Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Thu, 13 Jul 2023 04:43:17 -0400 Subject: [PATCH 015/151] Update the PrisonSpigotAPI to include a lot of new api endpoints for accessing sellall related functions. --- docs/changelog_v3.3.x.md | 3 + .../prison/spigot/api/PrisonSpigotAPI.java | 478 +++++++++++++++++- .../prison/spigot/sellall/SellAllUtil.java | 94 +++- 3 files changed, 564 insertions(+), 11 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 352a96cf8..c368ecabe 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -17,6 +17,9 @@ These change logs represent the work that has been going on within prison. # 3.3.0-alpha.15 2023-07-13 +* **Update the PrisonSpigotAPI to include a lot of new api endpoints for accessing sellall related functions.** + + * **Sellall: Expanded the functionality of the SellAllData obejcts to indicate if the items were sold.** diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/api/PrisonSpigotAPI.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/api/PrisonSpigotAPI.java index dc86a4839..c6d4a9d5b 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/api/PrisonSpigotAPI.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/api/PrisonSpigotAPI.java @@ -11,6 +11,7 @@ import org.bukkit.block.Block; import org.bukkit.entity.Player; import org.bukkit.event.block.BlockBreakEvent; +import org.bukkit.inventory.ItemStack; import tech.mcprison.prison.Prison; import tech.mcprison.prison.internal.block.PrisonBlock; @@ -30,8 +31,10 @@ import tech.mcprison.prison.spigot.SpigotPrison; import tech.mcprison.prison.spigot.backpacks.BackpacksUtil; import tech.mcprison.prison.spigot.block.SpigotBlock; +import tech.mcprison.prison.spigot.block.SpigotItemStack; import tech.mcprison.prison.spigot.game.SpigotPlayer; import tech.mcprison.prison.spigot.game.SpigotWorld; +import tech.mcprison.prison.spigot.sellall.SellAllData; import tech.mcprison.prison.spigot.sellall.SellAllUtil; import tech.mcprison.prison.util.ChatColor; import tech.mcprison.prison.util.Location; @@ -43,6 +46,10 @@ *

Use of these are at your own risk. Misuse can result in corruption of Prison's * internal data. *

+ * + *

If you need something special, then please ask on our discord server and we + * can probably provide it for you. + *

* */ public class PrisonSpigotAPI { @@ -438,8 +445,28 @@ public BackpacksUtil getPrisonBackpacks(){ } /** - * Get the whole SellAllUtil of Prison Sellall to manage what you + *

Get the whole SellAllUtil of Prison Sellall to manage what you * want of Prison SellAll. + *

+ * + *

WARNING: usage of this object is at your own risk! Functions will change, + * and will be eliminated. The majority of the functions that were in, and are + * in this object that are `public` were never intended to be used outside + * of prison. Many of the functions really should have been marked as private. + *

+ * + *

WARNING: The sellall functions will be undergoing major revisions and + * improvements in the near future. As such, do not rely on internal functions + * unless otherwise indicated. Some of the features that will be changing, is the + * support for all of prison's items and blocks, including custom blocks and items. + * Also Prison will be adding a very dynamic shop that will allow customization + * for each player rank, if desired. Hence why you should be careful when not using + * this API class. + *

+ * + *

It is highly suggested to use the exposed functions within this API class. + * As such, more have been added to get a variety of different data out of prison. + *

* * @return SellAllUtil - Null if Prison Sellall's disabled. * */ @@ -460,21 +487,454 @@ public SellAllUtil getPrisonSellAll(){ * * @param player * @return - * */ + */ + @Deprecated public Double getSellAllMoneyWithMultiplier(Player player){ + Double results = null; + - if (sellAll == null){ - sellAll = SpigotPrison.getInstance().getSellAllUtil(); - } - - if (sellAll != null){ - return sellAll.getPlayerInventoryValue( (SpigotPlayer)player ); + if (getPrisonSellAll() != null) { + + double value = 0; + + List soldItems = getPrisonSellAll().sellPlayerItems( player ); + for (SellAllData soldItem : soldItems) { + if ( soldItem != null ) { + value += soldItem.getTransactionAmount(); + } + } + // return sellAll.getSellMoney(player); + results = value; } - return null; + return results; + } + + /** + *

This function will calculate the value of all sellable items within the player's inventory + * and provide a total amount that they earned for the sales. + * This includes the calculated player's multipliers. + *

+ * + * @param player + * @return + */ + public double getPlayerInventoryValue(Player player) { + double results = 0; + + if (getPrisonSellAll() != null) { + + results = getPrisonSellAll().getPlayerInventoryValue( new SpigotPlayer(player) ); + } + + return results; + } + + /** + *

This function will calculate the value of the player's inventory that + * are sellable and then will generate + * a simple report listing everything that can be sold with their values. + *

+ * + *

Nothing is sold. No notifications are sent to the player. + *

+ * + *

See the function

getPlayerInventoryValueTransactions()
to + * gain access to the transaction logs for more information. + *

+ * + * @param player + * @return + */ + public String getPlayerInventoryValueReport(Player player) { + String results = null; + + if (getPrisonSellAll() != null) { + + results = getPrisonSellAll().getPlayerInventoryValueReport( new SpigotPlayer(player) ); + } + + return results; + } + + /** + *

This function calculates the value of the player's inventory items that are salable, + * and returns the transaction log within the collection of SellAllData. + *

+ * + *

Nothing is sold. No notifications are sent to the player. + *

+ * + *

To get the total transaction value, add all elements together. + * To generate a transaction report use the static function: + *

+ *
List itemsSold = prisonApi.getPlayerInventoryValueTransactions(Player player);
+	 *SellAllData.itemSoldReport( itemsSold );
+ * + * @param player + * @return transactionLogs + */ + public List getPlayerInventoryValueTransactions(Player player) { + List results = new ArrayList<>(); + + if (getPrisonSellAll() != null) { + + results = getPrisonSellAll().getPlayerInventoryValueTransactions( new SpigotPlayer(player) ); + } + + return results; + } + + + /** + *

This function will calculate the value of ItemStack + * and provide a total amount that would earn for the sales. + * This includes the calculated player's multipliers. + *

+ * + * @param player + * @param itemStack + * @return + */ + public double getItemStackValue(Player player, ItemStack itemStack ) { + double results = 0; + + if (getPrisonSellAll() != null) { + + results = getPrisonSellAll().getItemStackValue( + new SpigotPlayer(player), new SpigotItemStack(itemStack) ); + + } + + return results; + } + + /** + *

This function will calculate the value of the ItemStack that + * are sellable and then will generate + * a simple report listing everything that can be sold with their values. + *

+ * + *

Nothing is sold. No notifications are sent to the player. + *

+ * + *

See the function

getPlayerInventoryValueTransactions()
to + * gain access to the transaction logs for more information. + *

+ * + * @param player + * @param itemStack + * @return + */ + public String getItemStackValueReport(Player player, ItemStack itemStack ) { + String results = null; + + if (getPrisonSellAll() != null) { + + results = getPrisonSellAll().getItemStackValueReport( + new SpigotPlayer(player), new SpigotItemStack(itemStack) ); + + } + + return results; } + /** + *

This function calculates the value of the ItemStack that are salable, + * and returns the transaction log within the collection of SellAllData. + *

+ * + *

Nothing is sold. No notifications are sent to the player. + *

+ * + *

To get the total transaction value, add all elements together. + * To generate a transaction report use the static function: + *

+ *
List itemsSold = prisonApi.getPlayerInventoryValueTransactions(Player player);
+	 *SellAllData.itemSoldReport( itemsSold );
+ * + * @param player + * @param itemStack + * @return + */ + public List getItemStackValueTransactions(Player player, ItemStack itemStack ) { + List results = new ArrayList<>(); + + if (getPrisonSellAll() != null) { + + results = getPrisonSellAll().getItemStackValueTransactions( + new SpigotPlayer(player), new SpigotItemStack(itemStack) ); + + } + + return results; + } + + /** + *

This function sells anything within the player's inventory that is + * sellable. This function returns a transaction log of soldItems that can + * be summarized to get the total sales amount.

+ * + *

WARNING: This function REMOVES items from the player's inventory, but does + * NOT pay them any money!! If you are using this function, then + * you must sum all of the transactions and pay the player. + *

+ * + *

This is an exposed internal function that provides sellall capabilities without + * all of the complexities of the formal `sellAllSell()` functions. + * Use at your own risk. + *

+ * + *

This function does not notify the players, does not pay the players, + * does not provide all of the bells-and-whistles of customization within the + * sellall config files, and is basically a bare-bones sell it if it can be sold + * type of function. + *

+ * + * @param player + * @param itemStack + * @return + */ + public List sellPlayerItems(Player player ) { + List soldItems = new ArrayList<>(); + + if (getPrisonSellAll() != null) { + + soldItems = getPrisonSellAll().sellPlayerItems( player ); + } + + return soldItems; + } + + /** + *

This function sells anything within the ItemStack List that is + * sellable. This function returns a transaction log of soldItems that can + * be summarized to get the total sales amount.

+ * + *

WARNING: This function REMOVES items from the ItemStack that have been + * sold, but does NOT pay the player any money!! If you are + * using this function, then you must sum all of the + * transactions and pay the player. + *

+ * + *

This is an exposed internal function that provides sellall capabilities without + * all of the complexities of the formal `sellAllSell()` functions. + * Use at your own risk. + *

+ * + *

This function does not notify the players, does not pay the players, + * does not provide all of the bells-and-whistles of customization within the + * sellall config files, and is basically a bare-bones sell it if it can be sold + * type of function. + *

+ * + * @param player + * @param itemStacks + * @return + */ + public List sellPlayerItemStacks(Player player, List itemStacks ) { + List soldItems = new ArrayList<>(); + + if (getPrisonSellAll() != null) { + + List iStacks = new ArrayList<>(); + for (ItemStack itemStack : itemStacks) { + if ( itemStack != null ) { + iStacks.add( new SpigotItemStack( itemStack )); + } + } + + soldItems = getPrisonSellAll().sellPlayerItemStacks( player, iStacks ); + } + + return soldItems; + } + + + /** + *

This function will remove all sellable items from the player's Inventories. It will first ensure that a + * Player can sell the items. Some of the conditions that are checked are, along with some of the behaviors: + *

+ * + *
    + *
  • If player has access to use SellAll signs.
  • + *
  • Provide the amount the player earned if this is not disabled.
  • + *
  • If this actions is silenced, then text and audio notifications are suppressed.
  • + *
  • If configured, the reported earnings amount may be delayed and added to other earnings, + * which will reduce flooding the player with notifications.
  • + *
  • If sound notifications are enabled, then they will be played.
  • + * + *
+ * + *

Default usage of this method: + *

+ *
sellAllSell(p, false, false, true, true, false, true);
+ * + * @param p - Player. + * @param isUsingSign - boolean. + * @param completelySilent - boolean. + * @param notifyPlayerEarned - boolean. + * @param notifyPlayerDelay - boolean. + * @param notifyPlayerEarningDelay - boolean. + * @param playSoundOnSellAll - boolean. + * + * @return boolean If successful + * */ + public boolean sellAllSell(Player p, + boolean isUsingSign, + boolean completelySilent, + boolean notifyPlayerEarned, + boolean notifyPlayerDelay, + boolean notifyPlayerEarningDelay, + boolean playSoundOnSellAll) { + boolean results = false; + + if (getPrisonSellAll() != null) { + + results = getPrisonSellAll().sellAllSell( p, + isUsingSign, + completelySilent, + notifyPlayerEarned, + notifyPlayerDelay, + notifyPlayerEarningDelay, + playSoundOnSellAll, + null ); + } + + return results; + } + + /** + *

Performs a sellall of the player's inventory. + *

+ * + * @param p + * @param isUsingSign + * @param completelySilent + * @param notifyPlayerEarned + * @param notifyPlayerDelay + * @param notifyPlayerEarningDelay + * @param playSoundOnSellAll + * @param amounts + * @return + */ + public boolean sellAllSell(Player p, + boolean isUsingSign, + boolean completelySilent, + boolean notifyPlayerEarned, + boolean notifyPlayerDelay, + boolean notifyPlayerEarningDelay, + boolean playSoundOnSellAll, + List amounts ){ + boolean results = false; + + if (getPrisonSellAll() != null) { + + results = getPrisonSellAll().sellAllSell( p, + isUsingSign, completelySilent, + notifyPlayerEarned, notifyPlayerDelay, + notifyPlayerEarningDelay, playSoundOnSellAll, + amounts ); + } + + return results; + } + + /** + *

This function performs the sellall functions over an ItemStack. + *

+ * + * @param p + * @param itemStack + * @param completelySilent + * @param notifyPlayerEarned + * @param notifyPlayerEarningDelay + * @return + */ + public double sellAllSell(Player p, + SpigotItemStack itemStack, + boolean completelySilent, + boolean notifyPlayerEarned, + boolean notifyPlayerEarningDelay) + { + double results = 0; + + if (getPrisonSellAll() != null) { + + results = getPrisonSellAll().sellAllSell( p, + itemStack, + completelySilent, + notifyPlayerEarned, + notifyPlayerEarningDelay ); + } + + return results; + } + + + + /** + * Sell removing items from Inventories and checking all the possible conditions that a Player must meet to sell + * items, this includes method parameters like: + * - Is using SellAll Sign. + * - If tell the Player how much did he earn (if this's disabled by config, the parameter will be ignored). + * - If do this action without making the player notice it, disabling sounds and all messages. + * - If tell the Player to wait the end of SellAll Delay if not ended (if this's disabled by config, the parameter will be ignored). + * - If tell the Player how much did he earn only after a delay (AutoSell Delay Earnings will use this option for example). + * - If play sound on SellAll Sell (If sounds are disabled from the config, this parameter will be ignored. + * - If Sell only stuff from the input arrayList and not sell what is in the many Player inventories and supported backpacks. + * + * NOTE: With this method you can add an ArrayList of ItemStacks to sell, remove sold items (this will return the ArrayList without + * sold items), and give money to the player, also note that this will also trigger the usual sellall sell and sell everything sellable + * from all inventories and enabled backpacks of the Player. + * + * Return True if success, False if error or nothing changed or Player not meeting requirements. + * + * Default usage of this method: sellAllSell(p, itemStacks, false, false, true, false, false, true, false); + * + * @param p - Player. + * @param itemStacks - ArrayList of ItemStacks. + * @param isUsingSign - boolean. + * @param completelySilent - boolean. + * @param notifyPlayerEarned - boolean. + * @param notifyPlayerDelay - boolean. + * @param notifyPlayerEarningDelay - boolean. + * @param playSoundOnSellAll - boolean. + * @param sellInputArrayListOnly - boolean. + * + * @return Array of ItemStacks + * */ + public ArrayList sellAllSell(Player p, + ArrayList itemStacks, + boolean isUsingSign, + boolean completelySilent, + boolean notifyPlayerEarned, + boolean notifyPlayerDelay, + boolean notifyPlayerEarningDelay, + boolean playSoundOnSellAll, + boolean sellInputArrayListOnly){ + + ArrayList results = new ArrayList<>(); + + if (getPrisonSellAll() != null) { + + results = getPrisonSellAll().sellAllSell( p, + itemStacks, + isUsingSign, + completelySilent, + notifyPlayerEarned, + notifyPlayerDelay, + notifyPlayerEarningDelay, + playSoundOnSellAll, + sellInputArrayListOnly); + } + + return results; + } + + + /** *

Gets a player's current token balance. *

diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/sellall/SellAllUtil.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/sellall/SellAllUtil.java index 69c1188bc..23b128c8b 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/sellall/SellAllUtil.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/sellall/SellAllUtil.java @@ -606,6 +606,19 @@ public String getPlayerInventoryValueReport( SpigotPlayer sPlayer ) { return report; } + public List getPlayerInventoryValueTransactions( SpigotPlayer sPlayer ) { + + double multiplier = getPlayerMultiplier(sPlayer.getWrapper()); + + SpigotPlayerInventory spInventory = sPlayer.getSpigotPlayerInventory(); + + List soldItems = valueOfInventoryItems( spInventory, multiplier ); + + return soldItems; + } + + + public double getItemStackValue( SpigotPlayer player, SpigotItemStack itemStack ) { double multiplier = getPlayerMultiplier(player.getWrapper()); @@ -632,7 +645,30 @@ public String getItemStackValueReport( SpigotPlayer sPlayer, SpigotItemStack ite return report; } - private List sellPlayerItems(Player p) { + public List getItemStackValueTransactions( SpigotPlayer sPlayer, SpigotItemStack itemStack ) { + + double multiplier = getPlayerMultiplier(sPlayer.getWrapper()); + + List soldItems = new ArrayList<>(); + + SellAllData sad = sellItemStack( itemStack, multiplier ); + if ( sad != null ) { + + soldItems.add( sad ); + } + + return soldItems; + } + + /** + *

This sells the players inventory, and removes what is sold. + * This returns the transaction logs within the SellAllData obects. + *

+ * + * @param p + * @return + */ + public List sellPlayerItems(Player p) { double multiplier = getPlayerMultiplier(p); @@ -642,6 +678,59 @@ private List sellPlayerItems(Player p) { return sellInventoryItems( spInventory, multiplier ); } + + /** + *

This function sells the Item Stacks and returns a transaction log of items sold. + * This is an internal function. No messages are sent, most sellall options are bypassed, + * etc... Use at your own risk. + *

+ * + *

The parameter itemStacks will have the items sold removed. The sold items will + * be reflected in the returned transaction logs. + *

+ * + * @param p + * @param itemStacks + * @return + */ + public List sellPlayerItemStacks(Player p, + List itemStacks ) { + + double multiplier = getPlayerMultiplier(p); + + List soldItems = new ArrayList<>(); + + if ( itemStacks != null ) { + + List removable = new ArrayList<>(); + + // Go through all of the player's inventory and identify what can be sold. + // 1. if it can be sold, then create a SellAllData "receipt" + // 2. Add sad to the soldItems List + // 3. Add the ItemStack to the removable List to be removed later + for ( SpigotItemStack inv : itemStacks ) { + + SellAllData sad = sellItemStack( inv, multiplier ); + + if ( sad != null ) { + + sad.setItemsSold( true ); + + soldItems.add(sad); + + removable.add(inv); + } + } + + // We've identified all that could be sold, now remove them from the player's inventory + for (tech.mcprison.prison.internal.ItemStack itemStack : removable) { + itemStacks.remove( itemStack ); + } + } + + return soldItems; + } + private List sellInventoryItems( tech.mcprison.prison.internal.inventory.Inventory inventory, double multiplier ) { List soldItems = new ArrayList<>(); @@ -701,7 +790,8 @@ private List valueOfInventoryItems( * the transaction amount based upon how many items are in the itemStack, * times the salePrice, times the player's multiplier. * This function DOES NOT remove anything from any ItemStack, any Inventory, - * or any player's inventory. This just generates the transaction. + * or any player's inventory. This function does not pay the player + * anything. This just generates the transaction. *

* * @param iStack From db57d756aac379023a21e72e49d7f0e64d1b8407 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Thu, 13 Jul 2023 04:51:38 -0400 Subject: [PATCH 016/151] More work on getting the new worldguard sub-projejcts hooked up and functional in the build with gradle. --- docs/changelog_v3.3.x.md | 3 + prison-spigot/src/main/resources/config.yml | 29 +++++ prison-worldguard6/build.gradle | 7 +- prison-worldguard7/build.gradle | 76 +++++++++--- prison-worldguard7/build.gradle.txt | 116 ++++++++++++++++++ .../worldguard/PrisonWorldEdit7.java | 28 +++++ .../worldguard/PrisonWorldGuard7.java | 14 +++ settings.gradle | 7 ++ 8 files changed, 259 insertions(+), 21 deletions(-) create mode 100644 prison-worldguard7/build.gradle.txt create mode 100644 prison-worldguard7/src/main/java/tech/mcprison/worldguard7/worldguard/PrisonWorldEdit7.java create mode 100644 prison-worldguard7/src/main/java/tech/mcprison/worldguard7/worldguard/PrisonWorldGuard7.java diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index c368ecabe..bb3f06886 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -17,6 +17,9 @@ These change logs represent the work that has been going on within prison. # 3.3.0-alpha.15 2023-07-13 +* **More work on getting the new worldguard sub-projejcts hooked up and functional in the build with gradle.** + + * **Update the PrisonSpigotAPI to include a lot of new api endpoints for accessing sellall related functions.** diff --git a/prison-spigot/src/main/resources/config.yml b/prison-spigot/src/main/resources/config.yml index 3eaf8a39c..5b8f4265d 100644 --- a/prison-spigot/src/main/resources/config.yml +++ b/prison-spigot/src/main/resources/config.yml @@ -271,6 +271,35 @@ prison-mines: access-to-prior-mines: true tp-to-spawn-on-mine-resets: true enable-suffocation-in-mines: false + world-guard: + region-mine: + enable: true + name-prefix: prison_mine_ + permission-prefix: "g:prison.mines." + priority: 10 + deny-non-members: true + deny-message: You must rankup to access this mine. + flags: + block-break: true + item-pickup: true + xp-drops: true + item-drop: true + region-mine-area: + enable: true + name-prefix: prison_mine_area_ + increase-x: 15 + increase-z: 15 + increase-y: 9999 + permission-prefix: "g:prison.mines." + priority: 10 + deny-non-members: true + deny-message: You must rankup to access this mine. + flags: + block-break: false + item-pickup: true + xp-drops: true + item-drop: true + diff --git a/prison-worldguard6/build.gradle b/prison-worldguard6/build.gradle index 93874db44..224f74b31 100644 --- a/prison-worldguard6/build.gradle +++ b/prison-worldguard6/build.gradle @@ -74,20 +74,17 @@ dependencies { // implementation project(':prison-sellall') - // 1.9.4-R0.1-SNAPSHOT has been the version used for a long time: -// compileOnly 'org.spigotmc:spigot-api:1.9.4-R0.1-SNAPSHOT' - // 1.12.2-R0.1-SNAPSHOT works well: -// compileOnly 'org.spigotmc:spigot-api:1.12.2-R0.1-SNAPSHOT' - // 1.13.2 fails since deprecated functions have been removed. compileOnly 'org.spigotmc:spigot-api:1.13.2-R0.1-SNAPSHOT' // https://mvnrepository.com/artifact/com.sk89q.worldedit/worldedit-core + // Artifact located at repo: https://maven.enginehub.org/repo/ implementation 'com.sk89q.worldedit:worldedit-core:6.0.1' //implementation 'com.sk89q.worldedit:worldedit-core:7.2.15' // https://mvnrepository.com/artifact/com.sk89q.worldedit/worldedit-bukkit + // Artifact located at repo: https://maven.enginehub.org/repo/ compileOnly 'com.sk89q.worldedit:worldedit-bukkit:6.1.5' //compileOnly 'com.sk89q.worldedit:worldedit-bukkit:7.2.15' diff --git a/prison-worldguard7/build.gradle b/prison-worldguard7/build.gradle index 96a5b5e1d..c8b574c24 100644 --- a/prison-worldguard7/build.gradle +++ b/prison-worldguard7/build.gradle @@ -25,9 +25,45 @@ compileTestJava.options.encoding = "UTF-8" //sourceCompatibility = 1.8 + +// https://www.spigotmc.org/wiki/spigot-gradle/ + + repositories { mavenCentral() + + maven { + url = 'https://hub.spigotmc.org/nexus/content/repositories/snapshots/' + + // As of Gradle 5.1, you can limit this to only those + // dependencies you expect from it + content { + includeGroup 'org.bukkit' + includeGroup 'org.spigotmc' + } + } + /* + As Spigot-API depends on the BungeeCord ChatComponent-API, + we need to add the Sonatype OSS repository, as Gradle, + in comparison to maven, doesn't want to understand the ~/.m2 + directory unless added using mavenLocal(). Maven usually just gets + it from there, as most people have run the BuildTools at least once. + This is therefore not needed if you're using the full Spigot/CraftBukkit, + or if you're using the Bukkit API. + */ + maven { url = 'https://oss.sonatype.org/content/repositories/snapshots' } + maven { url = 'https://oss.sonatype.org/content/repositories/central' } + + // mavenLocal() // This is needed for CraftBukkit and Spigot. + maven { + url "https://mvnrepository.com/artifact" + } + + maven { url = "https://hub.spigotmc.org/nexus/content/groups/public" } + + + maven { url = "https://maven.enginehub.org/repo/" } } @@ -39,42 +75,50 @@ dependencies { // implementation project(':prison-sellall') + compileOnly 'org.spigotmc:spigot-api:1.13.2-R0.1-SNAPSHOT' + + + // API Docs: https://docs.enginehub.org/javadoc/com.sk89q.worldedit/worldedit-core/7.2.0/ + // https://mvnrepository.com/artifact/com.sk89q.worldedit/worldedit-core - implementation 'com.sk89q.worldedit:worldedit-core:6.0.1' - //implementation 'com.sk89q.worldedit:worldedit-core:7.2.15' + // Artifact located at repo: https://maven.enginehub.org/repo/ + //implementation 'com.sk89q.worldedit:worldedit-core:6.0.1' + implementation 'com.sk89q.worldedit:worldedit-core:7.2.15' // https://mvnrepository.com/artifact/com.sk89q.worldedit/worldedit-bukkit - compileOnly 'com.sk89q.worldedit:worldedit-bukkit:6.1.4' - //compileOnly 'com.sk89q.worldedit:worldedit-bukkit:7.2.15' + // Artifact located at repo: https://maven.enginehub.org/repo/ + //compileOnly 'com.sk89q.worldedit:worldedit-bukkit:6.1.5' + compileOnly 'com.sk89q.worldedit:worldedit-bukkit:7.2.15' // https://mvnrepository.com/artifact/com.sk89q.worldguard/worldguard-legacy - compileOnly 'com.sk89q.worldguard:worldguard-legacy:6.1.2' + // NOTE: although the following does exist, its unable to be pulled in so instead + // the jar is included. + //compileOnly 'com.sk89q.worldguard:worldguard-legacy:6.1.2' // https://mvnrepository.com/artifact/com.sk89q.worldguard/worldguard-core - //compileOnly 'com.sk89q.worldguard:worldguard-core:7.0.8' + // Artifact located at repo: https://maven.enginehub.org/repo/ + // WARNING: v7.0.4 is the last release that ia java 1.8 compatible + compileOnly 'com.sk89q.worldguard:worldguard-core:7.0.4' + //compileOnly 'com.sk89q.worldguard:worldguard-core:7.0.5' + // requires java 16: compileOnly 'com.sk89q.worldguard:worldguard-core:7.0.6' + // requires java 16: compileOnly 'com.sk89q.worldguard:worldguard-core:7.0.7' + // requires java 17: compileOnly 'com.sk89q.worldguard:worldguard-core:7.0.8' // https://mvnrepository.com/artifact/com.sk89q.worldguard/worldguard-bukkit + // Artifact located at repo: https://maven.enginehub.org/repo/ + compileOnly 'com.sk89q.worldguard:worldguard-bukkit:7.0.4' //compileOnly 'com.sk89q.worldguard:worldguard-bukkit:7.0.8' // https://mvnrepository.com/artifact/com.sk89q.worldguard.worldguard-libs/core + implementation 'com.sk89q.worldguard.worldguard-libs:core:7.0.4' //implementation 'com.sk89q.worldguard.worldguard-libs:core:7.0.8' - // 1.9.4-R0.1-SNAPSHOT has been the version used for a long time: -// compileOnly 'org.spigotmc:spigot-api:1.9.4-R0.1-SNAPSHOT' - // 1.12.2-R0.1-SNAPSHOT works well: -// compileOnly 'org.spigotmc:spigot-api:1.12.2-R0.1-SNAPSHOT' - // 1.13.2 fails since deprecated functions have been removed. - //compileOnly 'org.spigotmc:spigot-api:1.13.2-R0.1-SNAPSHOT' - - - - testImplementation group: 'junit', name: 'junit', version: '4.12' diff --git a/prison-worldguard7/build.gradle.txt b/prison-worldguard7/build.gradle.txt new file mode 100644 index 000000000..4997d8bb5 --- /dev/null +++ b/prison-worldguard7/build.gradle.txt @@ -0,0 +1,116 @@ +/* + * Prison is a Minecraft plugin for the prison game mode. + * Copyright (C) 2017 The Prison Team + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +group 'tech.mcprison' + +apply plugin: 'java' + +compileJava.options.encoding = 'UTF-8' +compileTestJava.options.encoding = "UTF-8" + +//sourceCompatibility = 1.8 + +repositories +{ + mavenCentral() +. + maven { + url = 'https://hub.spigotmc.org/nexus/content/repositories/snapshots/' + + // As of Gradle 5.1, you can limit this to only those + // dependencies you expect from it + content { + includeGroup 'org.bukkit' + includeGroup 'org.spigotmc' + } + } + /* + As Spigot-API depends on the BungeeCord ChatComponent-API, + we need to add the Sonatype OSS repository, as Gradle, + in comparison to maven, doesn't want to understand the ~/.m2 + directory unless added using mavenLocal(). Maven usually just gets + it from there, as most people have run the BuildTools at least once. + This is therefore not needed if you're using the full Spigot/CraftBukkit, + or if you're using the Bukkit API. + */ + maven { url = 'https://oss.sonatype.org/content/repositories/snapshots' } + maven { url = 'https://oss.sonatype.org/content/repositories/central' } + + // mavenLocal() // This is needed for CraftBukkit and Spigot. +// maven { +// url "https://mvnrepository.com/artifact" +// } + + //maven { url = "https://hub.spigotmc.org/nexus/content/groups/public" } + + //maven { url = "https://maven.enginehub.org/repo/" } + +} + + + +dependencies { + implementation project(':prison-core') +// implementation project(':prison-mines') +// implementation project(':prison-ranks') +// implementation project(':prison-sellall') + + + compileOnly 'org.spigotmc:spigot-api:1.13.2-R0.1-SNAPSHOT' + + + + // https://mvnrepository.com/artifact/com.sk89q.worldedit/worldedit-core + implementation 'com.sk89q.worldedit:worldedit-core:7.2.15' + + // https://mvnrepository.com/artifact/com.sk89q.worldedit/worldedit-bukkit + compileOnly 'com.sk89q.worldedit:worldedit-bukkit:7.2.15' + + + + + // https://mvnrepository.com/artifact/com.sk89q.worldguard/worldguard-core + compileOnly 'com.sk89q.worldguard:worldguard-core:7.0.8' + + // https://mvnrepository.com/artifact/com.sk89q.worldguard/worldguard-bukkit + compileOnly 'com.sk89q.worldguard:worldguard-bukkit:7.0.8' + + // https://mvnrepository.com/artifact/com.sk89q.worldguard.worldguard-libs/core + implementation 'com.sk89q.worldguard.worldguard-libs:core:7.0.8' + + + + + // 1.9.4-R0.1-SNAPSHOT has been the version used for a long time: +// compileOnly 'org.spigotmc:spigot-api:1.9.4-R0.1-SNAPSHOT' + // 1.12.2-R0.1-SNAPSHOT works well: +// compileOnly 'org.spigotmc:spigot-api:1.12.2-R0.1-SNAPSHOT' + // 1.13.2 fails since deprecated functions have been removed. + //compileOnly 'org.spigotmc:spigot-api:1.13.2-R0.1-SNAPSHOT' + + + + + + + testImplementation group: 'junit', name: 'junit', version: '4.12' + +} + + + diff --git a/prison-worldguard7/src/main/java/tech/mcprison/worldguard7/worldguard/PrisonWorldEdit7.java b/prison-worldguard7/src/main/java/tech/mcprison/worldguard7/worldguard/PrisonWorldEdit7.java new file mode 100644 index 000000000..d2055aab4 --- /dev/null +++ b/prison-worldguard7/src/main/java/tech/mcprison/worldguard7/worldguard/PrisonWorldEdit7.java @@ -0,0 +1,28 @@ +package tech.mcprison.worldguard7.worldguard; + +import tech.mcprison.prison.worldguard.PrisonWorldEdit; + +public class PrisonWorldEdit7 + extends PrisonWorldEdit +{ + + public PrisonWorldEdit7() { + super(); + + } + +// public void getWorldEditActor( org.bukkit.entity.Player bukkitPlayer ) { +// +//// Player results = BukkitAdapter.; +// +//// Bukkit +// +// +// +//// com.sk89q.worldedit.bukkit.BukkitPlayer; +//// BukkitAdapter.; +// +//// return results; +// } + +} diff --git a/prison-worldguard7/src/main/java/tech/mcprison/worldguard7/worldguard/PrisonWorldGuard7.java b/prison-worldguard7/src/main/java/tech/mcprison/worldguard7/worldguard/PrisonWorldGuard7.java new file mode 100644 index 000000000..0a6ab89a2 --- /dev/null +++ b/prison-worldguard7/src/main/java/tech/mcprison/worldguard7/worldguard/PrisonWorldGuard7.java @@ -0,0 +1,14 @@ +package tech.mcprison.worldguard7.worldguard; + +import tech.mcprison.prison.worldguard.PrisonWorldGuard; + +public class PrisonWorldGuard7 + extends PrisonWorldGuard +{ + + public PrisonWorldGuard7() { + super(); + + } + +} diff --git a/settings.gradle b/settings.gradle index a840f34b9..d12bb3e21 100644 --- a/settings.gradle +++ b/settings.gradle @@ -24,3 +24,10 @@ include 'prison-spigot' include 'prison-mines' include 'prison-ranks' include 'prison-sellall' + + +include 'prison-worldguard6' +include 'prison-worldguard7' +/* +include 'prison-worldguard8' +*/ From 901c7da5fe922379ff9569ffbcb2192ea15e2f58 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Fri, 14 Jul 2023 18:36:58 -0400 Subject: [PATCH 017/151] Prison Multi-Language Locale Manager: Possibly fixed a few issues with setting messages to "blanks". If the text of a message is removed, and set to an empty string, it should not be used. There was a situation where a zn_TW language file was set to an empty string and it was falling back to the en_US version. I found that there was a bug with a sendMessage() function to a player that was not bypassing the message like the other functions were doing. Also in the code where it was calculating the Locale variations, it was not accepting a blank as the final input. This was fixed. Also, to be clear, or more specific, I added a new keyword `*none*` to serve the same purpose. So either an empty string can be used, or that new `*none*` key word. --- .../prison/localization/LocaleManager.java | 14 ++++++++++++++ .../mcprison/prison/localization/Localizable.java | 14 +++++++++++++- 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/prison-core/src/main/java/tech/mcprison/prison/localization/LocaleManager.java b/prison-core/src/main/java/tech/mcprison/prison/localization/LocaleManager.java index bdf29f826..c8c6f1181 100755 --- a/prison-core/src/main/java/tech/mcprison/prison/localization/LocaleManager.java +++ b/prison-core/src/main/java/tech/mcprison/prison/localization/LocaleManager.java @@ -83,6 +83,8 @@ public class LocaleManager { private static final String DEFAULT_LOCALE = "en_US"; private static final String LOCALE_FOLDER = "lang"; + public static final String IGNORE_TEXT_NO_MESSAGE_INTENDED = "*none*"; + public static final String LOCALE_ERROR__CONFIG_LANG_NOT_FOUND = "local.error.configNotFound"; public static final String LOCALE_ERROR__FALLBACK_COUNT = "local.error.fallbackcount"; @@ -115,6 +117,13 @@ public class LocaleManager { ALTERNATIVES.put("pt_PT", Arrays.asList("pt_BR", "en_US")); ALTERNATIVES.put("ro_RO", Arrays.asList("en_US")); + + // Chinese dialects + ALTERNATIVES.put("zh_TW", Arrays.asList("zh_TW", "en_US")); + ALTERNATIVES.put("zh_CN", Arrays.asList("zh_CN", "en_US")); + // NOTE: many files are named with "-" dash and not underscore... so have both settings + ALTERNATIVES.put("zh-CN", Arrays.asList("zh-CN", "en_US")); + } private final PluginEntity module; @@ -702,6 +711,11 @@ private void loadLocale(String name, InputStream is, boolean printStackTrace) { String[] keyValue = line.split( "\\=" ); String value = (keyValue.length > 1 ? keyValue[1] : ""); // StringEscapeUtils.escapeJava( keyValue[1] ); + +// if ( IGNORE_TEXT_NO_MESSAGE_INTENDED.equalsIgnoreCase(value) ) { +// value = ""; +// } + temp.put( keyValue[0], value ); } diff --git a/prison-core/src/main/java/tech/mcprison/prison/localization/Localizable.java b/prison-core/src/main/java/tech/mcprison/prison/localization/Localizable.java index ca25eec0c..cd0504a27 100755 --- a/prison-core/src/main/java/tech/mcprison/prison/localization/Localizable.java +++ b/prison-core/src/main/java/tech/mcprison/prison/localization/Localizable.java @@ -245,6 +245,13 @@ private String localizeIn(String locale, boolean recursive, String... fallbacks) Properties props = getParent().getConfigs().get(locale); if (props.containsKey(getKey())) { // check if the message is defined in the locale String message = (String) props.get(getKey()); // yay, it worked + + // If the entry has been marked with "*none*" or an empty String then return an empty String: + if ( LocaleManager.IGNORE_TEXT_NO_MESSAGE_INTENDED.equalsIgnoreCase(message) || + message != null && message.trim().length() == 0 ) { + return ""; + } + if (replacements != null) { for (int i = 0; i < replacements.length; i++) { // replace placeholder sequences message = message @@ -380,7 +387,12 @@ public void sendTo(CommandSender sender, LogLevel level) { * @param sender The {@link CommandSender} to send this {@link Localizable} to */ public void sendTo(CommandSender sender) { - sendTo(sender, LogLevel.PLAIN); + + String message = localize(); + if ( message != null && !message.isEmpty() ) { + + sendTo(sender, LogLevel.PLAIN); + } } /** From 1f8e94695a433c575ddc0e7f4da7eb75f0e68b1b Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Fri, 14 Jul 2023 18:40:12 -0400 Subject: [PATCH 018/151] Prison Multi-Language Locale Manager: Updated all language files to include information about the new `*none*` keyword. This keyword is case insensitive and will return an empty string for that message component if it's part of a compound message. If the message is supposed to be sent to a player, it will be bypassed and nothing will be sent. --- docs/changelog_v3.3.x.md | 17 ++++++++++++++--- .../main/resources/lang/core/de_DE.properties | 9 +++++++++ .../main/resources/lang/core/en_GB.properties | 9 +++++++++ .../main/resources/lang/core/en_US.properties | 9 +++++++++ .../main/resources/lang/core/es_ES.properties | 9 +++++++++ .../main/resources/lang/core/fi_FI.properties | 9 +++++++++ .../main/resources/lang/core/fr_FR.properties | 9 +++++++++ .../main/resources/lang/core/hu_HU.properties | 9 +++++++++ .../main/resources/lang/core/it_IT.properties | 9 +++++++++ .../main/resources/lang/core/nl_BE.properties | 9 +++++++++ .../main/resources/lang/core/nl_NL.properties | 9 +++++++++ .../main/resources/lang/core/pt_PT.properties | 9 +++++++++ .../main/resources/lang/core/ro_RO.properties | 9 +++++++++ .../main/resources/lang/core/zh-CN.properties | 9 +++++++++ .../main/resources/lang/core/zh_TW.properties | 9 +++++++++ .../main/resources/lang/mines/de_DE.properties | 9 +++++++++ .../main/resources/lang/mines/en_US.properties | 9 +++++++++ .../main/resources/lang/mines/es_ES.properties | 9 +++++++++ .../main/resources/lang/mines/fi_FI.properties | 9 +++++++++ .../main/resources/lang/mines/fr_FR.properties | 9 +++++++++ .../main/resources/lang/mines/hu_HU.properties | 9 +++++++++ .../main/resources/lang/mines/it_IT.properties | 9 +++++++++ .../main/resources/lang/mines/nl_BE.properties | 9 +++++++++ .../main/resources/lang/mines/nl_NL.properties | 9 +++++++++ .../main/resources/lang/mines/pt_PT.properties | 9 +++++++++ .../main/resources/lang/mines/ro_RO.properties | 9 +++++++++ .../main/resources/lang/mines/zh-CN.properties | 9 +++++++++ .../main/resources/lang/mines/zh_TW.properties | 9 +++++++++ .../main/resources/lang/ranks/en_US.properties | 9 +++++++++ .../main/resources/lang/ranks/fr_FR.properties | 9 +++++++++ .../main/resources/lang/ranks/pt_PT.properties | 9 +++++++++ .../main/resources/lang/ranks/zh-CN.properties | 9 +++++++++ .../main/resources/lang/ranks/zh_TW.properties | 15 ++++++++++++--- .../resources/lang/sellall/en_US.properties | 10 ++++++++++ .../resources/lang/sellall/fi_FI.properties | 16 +++++++++++++--- .../resources/lang/sellall/fr_FR.properties | 10 ++++++++++ .../resources/lang/sellall/pt_PT.properties | 10 ++++++++++ .../resources/lang/sellall/zh_CN.properties | 10 ++++++++++ .../main/resources/lang/spigot/en_US.properties | 10 ++++++++++ .../main/resources/lang/spigot/fr_FR.properties | 10 ++++++++++ .../main/resources/lang/spigot/pt_PT.properties | 10 ++++++++++ .../main/resources/lang/spigot/zh-CN.properties | 10 ++++++++++ 42 files changed, 398 insertions(+), 9 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index bb3f06886..985f6d37e 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -14,16 +14,27 @@ These change logs represent the work that has been going on within prison. -# 3.3.0-alpha.15 2023-07-13 +# 3.3.0-alpha.15 2023-07-14 -* **More work on getting the new worldguard sub-projejcts hooked up and functional in the build with gradle.** +* **Prison Multi-Language Locale Manager: Updated all language files to include information about the new `*none*` keyword.** +This keyword is case insensitive and will return an empty string for that message component if it's part of a compound message. If the message is supposed to be sent to a player, it will be bypassed and nothing will be sent. + + +* **Prison Multi-Language Locale Manager: Possibly fixed a few issues with setting messages to "blanks". If the text of a message is removed, and set to an empty string, it should not be used.** +There was a situation where a zn_TW language file was set to an empty string and it was falling back to the en_US version. +I found that there was a bug with a sendMessage() function to a player that was not bypassing the message like the other functions were doing. +Also in the code where it was calculating the Locale variations, it was not accepting a blank as the final input. This was fixed. +Also, to be clear, or more specific, I added a new keyword `*none*` to serve the same purpose. So either an empty string can be used, or that new `*none*` key word. + + +* **More work on getting the new world guard sub-projects hooked up and functional in the build with gradle.** * **Update the PrisonSpigotAPI to include a lot of new api endpoints for accessing sellall related functions.** -* **Sellall: Expanded the functionality of the SellAllData obejcts to indicate if the items were sold.** +* **Sellall: Expanded the functionality of the SellAllData obejects to indicate if the items were sold.** * **New sellall features: 'sellall valueof' calculates the value of everything in the player's inventory that can be sold. '/sellall valueofHand' calculates what is held in the player's hand.** diff --git a/prison-core/src/main/resources/lang/core/de_DE.properties b/prison-core/src/main/resources/lang/core/de_DE.properties index deb59d124..572803be6 100644 --- a/prison-core/src/main/resources/lang/core/de_DE.properties +++ b/prison-core/src/main/resources/lang/core/de_DE.properties @@ -64,6 +64,15 @@ # renamed files will never be deleted by prison; you can remove them when you feel like it # is safe to do so. # +# NOTE: If you need to eliminate a message, leave an empty String after the equal sign `=`, or +# use the key word `*none*`. Prison will not insert element or send a message if +# these values are found. +# Example: `core_text__from_now=from now` use either `core_text__from_now=` or `core_text__from_now=*none*` +# +# NOTE: Specific to the `core_output__` messages, `/prison reload locales` cannot reload them because +# these are a very low level static component of the fallback messaging system within Prison. +# You will have to restart the server if you make any changes to the messages with these prefixes. +# # Please consider helping Prison, and everyone else who may use Prison, by contributing all # translations to other languages. They should be faithful translations, and not something # for the sake of humor or changes just for cosmetic styling. If you have something you would diff --git a/prison-core/src/main/resources/lang/core/en_GB.properties b/prison-core/src/main/resources/lang/core/en_GB.properties index f9b079bd7..b9bed0f09 100644 --- a/prison-core/src/main/resources/lang/core/en_GB.properties +++ b/prison-core/src/main/resources/lang/core/en_GB.properties @@ -61,6 +61,15 @@ # renamed files will never be deleted by prison; you can remove them when you feel like it # is safe to do so. # +# NOTE: If you need to eliminate a message, leave an empty String after the equal sign `=`, or +# use the key word `*none*`. Prison will not insert element or send a message if +# these values are found. +# Example: `core_text__from_now=from now` use either `core_text__from_now=` or `core_text__from_now=*none*` +# +# NOTE: Specific to the `core_output__` messages, `/prison reload locales` cannot reload them because +# these are a very low level static component of the fallback messaging system within Prison. +# You will have to restart the server if you make any changes to the messages with these prefixes. +# # Please consider helping Prison, and everyone else who may use Prison, by contributing all # translations to other languages. They should be faithful translations, and not something # for the sake of humor or changes just for cosmetic styling. If you have something you would diff --git a/prison-core/src/main/resources/lang/core/en_US.properties b/prison-core/src/main/resources/lang/core/en_US.properties index 9533f6cea..c433981d7 100644 --- a/prison-core/src/main/resources/lang/core/en_US.properties +++ b/prison-core/src/main/resources/lang/core/en_US.properties @@ -61,6 +61,15 @@ # renamed files will never be deleted by prison; you can remove them when you feel like it # is safe to do so. # +# NOTE: If you need to eliminate a message, leave an empty String after the equal sign `=`, or +# use the key word `*none*`. Prison will not insert element or send a message if +# these values are found. +# Example: `core_text__from_now=from now` use either `core_text__from_now=` or `core_text__from_now=*none*` +# +# NOTE: Specific to the `core_output__` messages, `/prison reload locales` cannot reload them because +# these are a very low level static component of the fallback messaging system within Prison. +# You will have to restart the server if you make any changes to the messages with these prefixes. +# # Please consider helping Prison, and everyone else who may use Prison, by contributing all # translations to other languages. They should be faithful translations, and not something # for the sake of humor or changes just for cosmetic styling. If you have something you would diff --git a/prison-core/src/main/resources/lang/core/es_ES.properties b/prison-core/src/main/resources/lang/core/es_ES.properties index 590e00ba6..48c2aaebc 100644 --- a/prison-core/src/main/resources/lang/core/es_ES.properties +++ b/prison-core/src/main/resources/lang/core/es_ES.properties @@ -61,6 +61,15 @@ # renamed files will never be deleted by prison; you can remove them when you feel like it # is safe to do so. # +# NOTE: If you need to eliminate a message, leave an empty String after the equal sign `=`, or +# use the key word `*none*`. Prison will not insert element or send a message if +# these values are found. +# Example: `core_text__from_now=from now` use either `core_text__from_now=` or `core_text__from_now=*none*` +# +# NOTE: Specific to the `core_output__` messages, `/prison reload locales` cannot reload them because +# these are a very low level static component of the fallback messaging system within Prison. +# You will have to restart the server if you make any changes to the messages with these prefixes. +# # Please consider helping Prison, and everyone else who may use Prison, by contributing all # translations to other languages. They should be faithful translations, and not something # for the sake of humor or changes just for cosmetic styling. If you have something you would diff --git a/prison-core/src/main/resources/lang/core/fi_FI.properties b/prison-core/src/main/resources/lang/core/fi_FI.properties index 424e2488a..d7dcd6e37 100644 --- a/prison-core/src/main/resources/lang/core/fi_FI.properties +++ b/prison-core/src/main/resources/lang/core/fi_FI.properties @@ -61,6 +61,15 @@ # renamed files will never be deleted by prison; you can remove them when you feel like it # is safe to do so. # +# NOTE: If you need to eliminate a message, leave an empty String after the equal sign `=`, or +# use the key word `*none*`. Prison will not insert element or send a message if +# these values are found. +# Example: `core_text__from_now=from now` use either `core_text__from_now=` or `core_text__from_now=*none*` +# +# NOTE: Specific to the `core_output__` messages, `/prison reload locales` cannot reload them because +# these are a very low level static component of the fallback messaging system within Prison. +# You will have to restart the server if you make any changes to the messages with these prefixes. +# # Please consider helping Prison, and everyone else who may use Prison, by contributing all # translations to other languages. They should be faithful translations, and not something # for the sake of humor or changes just for cosmetic styling. If you have something you would diff --git a/prison-core/src/main/resources/lang/core/fr_FR.properties b/prison-core/src/main/resources/lang/core/fr_FR.properties index d33f66512..ad4ac402b 100644 --- a/prison-core/src/main/resources/lang/core/fr_FR.properties +++ b/prison-core/src/main/resources/lang/core/fr_FR.properties @@ -61,6 +61,15 @@ # renamed files will never be deleted by prison; you can remove them when you feel like it # is safe to do so. # +# NOTE: If you need to eliminate a message, leave an empty String after the equal sign `=`, or +# use the key word `*none*`. Prison will not insert element or send a message if +# these values are found. +# Example: `core_text__from_now=from now` use either `core_text__from_now=` or `core_text__from_now=*none*` +# +# NOTE: Specific to the `core_output__` messages, `/prison reload locales` cannot reload them because +# these are a very low level static component of the fallback messaging system within Prison. +# You will have to restart the server if you make any changes to the messages with these prefixes. +# # Please consider helping Prison, and everyone else who may use Prison, by contributing all # translations to other languages. They should be faithful translations, and not something # for the sake of humor or changes just for cosmetic styling. If you have something you would diff --git a/prison-core/src/main/resources/lang/core/hu_HU.properties b/prison-core/src/main/resources/lang/core/hu_HU.properties index 6dcfc75bc..8c8534d30 100644 --- a/prison-core/src/main/resources/lang/core/hu_HU.properties +++ b/prison-core/src/main/resources/lang/core/hu_HU.properties @@ -61,6 +61,15 @@ # renamed files will never be deleted by prison; you can remove them when you feel like it # is safe to do so. # +# NOTE: If you need to eliminate a message, leave an empty String after the equal sign `=`, or +# use the key word `*none*`. Prison will not insert element or send a message if +# these values are found. +# Example: `core_text__from_now=from now` use either `core_text__from_now=` or `core_text__from_now=*none*` +# +# NOTE: Specific to the `core_output__` messages, `/prison reload locales` cannot reload them because +# these are a very low level static component of the fallback messaging system within Prison. +# You will have to restart the server if you make any changes to the messages with these prefixes. +# # Please consider helping Prison, and everyone else who may use Prison, by contributing all # translations to other languages. They should be faithful translations, and not something # for the sake of humor or changes just for cosmetic styling. If you have something you would diff --git a/prison-core/src/main/resources/lang/core/it_IT.properties b/prison-core/src/main/resources/lang/core/it_IT.properties index 3da4b9a97..28485c49b 100644 --- a/prison-core/src/main/resources/lang/core/it_IT.properties +++ b/prison-core/src/main/resources/lang/core/it_IT.properties @@ -61,6 +61,15 @@ # renamed files will never be deleted by prison; you can remove them when you feel like it # is safe to do so. # +# NOTE: If you need to eliminate a message, leave an empty String after the equal sign `=`, or +# use the key word `*none*`. Prison will not insert element or send a message if +# these values are found. +# Example: `core_text__from_now=from now` use either `core_text__from_now=` or `core_text__from_now=*none*` +# +# NOTE: Specific to the `core_output__` messages, `/prison reload locales` cannot reload them because +# these are a very low level static component of the fallback messaging system within Prison. +# You will have to restart the server if you make any changes to the messages with these prefixes. +# # Please consider helping Prison, and everyone else who may use Prison, by contributing all # translations to other languages. They should be faithful translations, and not something # for the sake of humor or changes just for cosmetic styling. If you have something you would diff --git a/prison-core/src/main/resources/lang/core/nl_BE.properties b/prison-core/src/main/resources/lang/core/nl_BE.properties index 6e970e303..729dbc373 100644 --- a/prison-core/src/main/resources/lang/core/nl_BE.properties +++ b/prison-core/src/main/resources/lang/core/nl_BE.properties @@ -61,6 +61,15 @@ # renamed files will never be deleted by prison; you can remove them when you feel like it # is safe to do so. # +# NOTE: If you need to eliminate a message, leave an empty String after the equal sign `=`, or +# use the key word `*none*`. Prison will not insert element or send a message if +# these values are found. +# Example: `core_text__from_now=from now` use either `core_text__from_now=` or `core_text__from_now=*none*` +# +# NOTE: Specific to the `core_output__` messages, `/prison reload locales` cannot reload them because +# these are a very low level static component of the fallback messaging system within Prison. +# You will have to restart the server if you make any changes to the messages with these prefixes. +# # Please consider helping Prison, and everyone else who may use Prison, by contributing all # translations to other languages. They should be faithful translations, and not something # for the sake of humor or changes just for cosmetic styling. If you have something you would diff --git a/prison-core/src/main/resources/lang/core/nl_NL.properties b/prison-core/src/main/resources/lang/core/nl_NL.properties index f8be4ce03..a57dccea0 100644 --- a/prison-core/src/main/resources/lang/core/nl_NL.properties +++ b/prison-core/src/main/resources/lang/core/nl_NL.properties @@ -61,6 +61,15 @@ # renamed files will never be deleted by prison; you can remove them when you feel like it # is safe to do so. # +# NOTE: If you need to eliminate a message, leave an empty String after the equal sign `=`, or +# use the key word `*none*`. Prison will not insert element or send a message if +# these values are found. +# Example: `core_text__from_now=from now` use either `core_text__from_now=` or `core_text__from_now=*none*` +# +# NOTE: Specific to the `core_output__` messages, `/prison reload locales` cannot reload them because +# these are a very low level static component of the fallback messaging system within Prison. +# You will have to restart the server if you make any changes to the messages with these prefixes. +# # Please consider helping Prison, and everyone else who may use Prison, by contributing all # translations to other languages. They should be faithful translations, and not something # for the sake of humor or changes just for cosmetic styling. If you have something you would diff --git a/prison-core/src/main/resources/lang/core/pt_PT.properties b/prison-core/src/main/resources/lang/core/pt_PT.properties index 0a3281bf5..f2cac4109 100644 --- a/prison-core/src/main/resources/lang/core/pt_PT.properties +++ b/prison-core/src/main/resources/lang/core/pt_PT.properties @@ -61,6 +61,15 @@ # renamed files will never be deleted by prison; you can remove them when you feel like it # is safe to do so. # +# NOTE: If you need to eliminate a message, leave an empty String after the equal sign `=`, or +# use the key word `*none*`. Prison will not insert element or send a message if +# these values are found. +# Example: `core_text__from_now=from now` use either `core_text__from_now=` or `core_text__from_now=*none*` +# +# NOTE: Specific to the `core_output__` messages, `/prison reload locales` cannot reload them because +# these are a very low level static component of the fallback messaging system within Prison. +# You will have to restart the server if you make any changes to the messages with these prefixes. +# # Please consider helping Prison, and everyone else who may use Prison, by contributing all # translations to other languages. They should be faithful translations, and not something # for the sake of humor or changes just for cosmetic styling. If you have something you would diff --git a/prison-core/src/main/resources/lang/core/ro_RO.properties b/prison-core/src/main/resources/lang/core/ro_RO.properties index ed5bf728a..285e21b41 100644 --- a/prison-core/src/main/resources/lang/core/ro_RO.properties +++ b/prison-core/src/main/resources/lang/core/ro_RO.properties @@ -59,6 +59,15 @@ # nefiind È™ters, poÈ›i integra manual schimbările în fiÈ™ierul nou. FiÈ™ierele vechi, redenumite # nu vor fi È™terse de către Prison; poÈ›i să le È™tergi când consideri că este sigur să o faci. # +# NOTE: If you need to eliminate a message, leave an empty String after the equal sign `=`, or +# use the key word `*none*`. Prison will not insert element or send a message if +# these values are found. +# Example: `core_text__from_now=from now` use either `core_text__from_now=` or `core_text__from_now=*none*` +# +# NOTE: Specific to the `core_output__` messages, `/prison reload locales` cannot reload them because +# these are a very low level static component of the fallback messaging system within Prison. +# You will have to restart the server if you make any changes to the messages with these prefixes. +# # PuteÈ›i ajuta Prison È™i utilizatorii acestuia prin a adăuga traduceri în alte limbi. # Acestea ar trebui să fie traduceri precise, ce menÈ›in înÈ›elesul mesajului original, # fără glume de prost gust È™i abateri de la semnificaÈ›ia originală. Dacă doreÈ™ti să diff --git a/prison-core/src/main/resources/lang/core/zh-CN.properties b/prison-core/src/main/resources/lang/core/zh-CN.properties index 3d48d2fc8..c4bcb227d 100644 --- a/prison-core/src/main/resources/lang/core/zh-CN.properties +++ b/prison-core/src/main/resources/lang/core/zh-CN.properties @@ -62,6 +62,15 @@ # renamed files will never be deleted by prison; you can remove them when you feel like it # is safe to do so. # +# NOTE: If you need to eliminate a message, leave an empty String after the equal sign `=`, or +# use the key word `*none*`. Prison will not insert element or send a message if +# these values are found. +# Example: `core_text__from_now=from now` use either `core_text__from_now=` or `core_text__from_now=*none*` +# +# NOTE: Specific to the `core_output__` messages, `/prison reload locales` cannot reload them because +# these are a very low level static component of the fallback messaging system within Prison. +# You will have to restart the server if you make any changes to the messages with these prefixes. +# # Please consider helping Prison, and everyone else who may use Prison, by contributing all # translations to other languages. They should be faithful translations, and not something # for the sake of humor or changes just for cosmetic styling. If you have something you would diff --git a/prison-core/src/main/resources/lang/core/zh_TW.properties b/prison-core/src/main/resources/lang/core/zh_TW.properties index 7cc23d779..2f516ffc7 100644 --- a/prison-core/src/main/resources/lang/core/zh_TW.properties +++ b/prison-core/src/main/resources/lang/core/zh_TW.properties @@ -61,6 +61,15 @@ # renamed files will never be deleted by prison; you can remove them when you feel like it # is safe to do so. # +# NOTE: If you need to eliminate a message, leave an empty String after the equal sign `=`, or +# use the key word `*none*`. Prison will not insert element or send a message if +# these values are found. +# Example: `core_text__from_now=from now` use either `core_text__from_now=` or `core_text__from_now=*none*` +# +# NOTE: Specific to the `core_output__` messages, `/prison reload locales` cannot reload them because +# these are a very low level static component of the fallback messaging system within Prison. +# You will have to restart the server if you make any changes to the messages with these prefixes. +# # Please consider helping Prison, and everyone else who may use Prison, by contributing all # translations to other languages. They should be faithful translations, and not something # for the sake of humor or changes just for cosmetic styling. If you have something you would diff --git a/prison-core/src/main/resources/lang/mines/de_DE.properties b/prison-core/src/main/resources/lang/mines/de_DE.properties index b8c0f73f4..da99ff80f 100644 --- a/prison-core/src/main/resources/lang/mines/de_DE.properties +++ b/prison-core/src/main/resources/lang/mines/de_DE.properties @@ -49,6 +49,15 @@ ## /prison support submit. ## +# NOTE: If you need to eliminate a message, leave an empty String after the equal sign `=`, or +# use the key word `*none*`. Prison will not insert element or send a message if +# these values are found. +# Example: `core_text__from_now=from now` use either `core_text__from_now=` or `core_text__from_now=*none*` +# +# NOTE: Specific to the `core_output__` messages, `/prison reload locales` cannot reload them because +# these are a very low level static component of the fallback messaging system within Prison. +# You will have to restart the server if you make any changes to the messages with these prefixes. +# messages__version=4 diff --git a/prison-core/src/main/resources/lang/mines/en_US.properties b/prison-core/src/main/resources/lang/mines/en_US.properties index 3f86d76e8..d7c409967 100644 --- a/prison-core/src/main/resources/lang/mines/en_US.properties +++ b/prison-core/src/main/resources/lang/mines/en_US.properties @@ -49,6 +49,15 @@ ## /prison support submit. ## +# NOTE: If you need to eliminate a message, leave an empty String after the equal sign `=`, or +# use the key word `*none*`. Prison will not insert element or send a message if +# these values are found. +# Example: `core_text__from_now=from now` use either `core_text__from_now=` or `core_text__from_now=*none*` +# +# NOTE: Specific to the `core_output__` messages, `/prison reload locales` cannot reload them because +# these are a very low level static component of the fallback messaging system within Prison. +# You will have to restart the server if you make any changes to the messages with these prefixes. +# messages__version=4 diff --git a/prison-core/src/main/resources/lang/mines/es_ES.properties b/prison-core/src/main/resources/lang/mines/es_ES.properties index c6bbeb44f..11692e63a 100644 --- a/prison-core/src/main/resources/lang/mines/es_ES.properties +++ b/prison-core/src/main/resources/lang/mines/es_ES.properties @@ -49,6 +49,15 @@ ## /prison support submit. ## +# NOTE: If you need to eliminate a message, leave an empty String after the equal sign `=`, or +# use the key word `*none*`. Prison will not insert element or send a message if +# these values are found. +# Example: `core_text__from_now=from now` use either `core_text__from_now=` or `core_text__from_now=*none*` +# +# NOTE: Specific to the `core_output__` messages, `/prison reload locales` cannot reload them because +# these are a very low level static component of the fallback messaging system within Prison. +# You will have to restart the server if you make any changes to the messages with these prefixes. +# messages__version=4 diff --git a/prison-core/src/main/resources/lang/mines/fi_FI.properties b/prison-core/src/main/resources/lang/mines/fi_FI.properties index 0600f57f3..4d8607849 100644 --- a/prison-core/src/main/resources/lang/mines/fi_FI.properties +++ b/prison-core/src/main/resources/lang/mines/fi_FI.properties @@ -49,6 +49,15 @@ ## /prison support submit. ## +# NOTE: If you need to eliminate a message, leave an empty String after the equal sign `=`, or +# use the key word `*none*`. Prison will not insert element or send a message if +# these values are found. +# Example: `core_text__from_now=from now` use either `core_text__from_now=` or `core_text__from_now=*none*` +# +# NOTE: Specific to the `core_output__` messages, `/prison reload locales` cannot reload them because +# these are a very low level static component of the fallback messaging system within Prison. +# You will have to restart the server if you make any changes to the messages with these prefixes. +# messages__version=4 diff --git a/prison-core/src/main/resources/lang/mines/fr_FR.properties b/prison-core/src/main/resources/lang/mines/fr_FR.properties index 4928b82e5..d6cf696c7 100644 --- a/prison-core/src/main/resources/lang/mines/fr_FR.properties +++ b/prison-core/src/main/resources/lang/mines/fr_FR.properties @@ -49,6 +49,15 @@ ## /prison support submit. ## +# NOTE: If you need to eliminate a message, leave an empty String after the equal sign `=`, or +# use the key word `*none*`. Prison will not insert element or send a message if +# these values are found. +# Example: `core_text__from_now=from now` use either `core_text__from_now=` or `core_text__from_now=*none*` +# +# NOTE: Specific to the `core_output__` messages, `/prison reload locales` cannot reload them because +# these are a very low level static component of the fallback messaging system within Prison. +# You will have to restart the server if you make any changes to the messages with these prefixes. +# messages__version=4 diff --git a/prison-core/src/main/resources/lang/mines/hu_HU.properties b/prison-core/src/main/resources/lang/mines/hu_HU.properties index 8748e42d6..e1d896577 100644 --- a/prison-core/src/main/resources/lang/mines/hu_HU.properties +++ b/prison-core/src/main/resources/lang/mines/hu_HU.properties @@ -49,6 +49,15 @@ ## /prison support submit. ## +# NOTE: If you need to eliminate a message, leave an empty String after the equal sign `=`, or +# use the key word `*none*`. Prison will not insert element or send a message if +# these values are found. +# Example: `core_text__from_now=from now` use either `core_text__from_now=` or `core_text__from_now=*none*` +# +# NOTE: Specific to the `core_output__` messages, `/prison reload locales` cannot reload them because +# these are a very low level static component of the fallback messaging system within Prison. +# You will have to restart the server if you make any changes to the messages with these prefixes. +# messages__version=4 diff --git a/prison-core/src/main/resources/lang/mines/it_IT.properties b/prison-core/src/main/resources/lang/mines/it_IT.properties index ee9efefba..e3e9aea98 100644 --- a/prison-core/src/main/resources/lang/mines/it_IT.properties +++ b/prison-core/src/main/resources/lang/mines/it_IT.properties @@ -49,6 +49,15 @@ ## /prison support submit. ## +# NOTE: If you need to eliminate a message, leave an empty String after the equal sign `=`, or +# use the key word `*none*`. Prison will not insert element or send a message if +# these values are found. +# Example: `core_text__from_now=from now` use either `core_text__from_now=` or `core_text__from_now=*none*` +# +# NOTE: Specific to the `core_output__` messages, `/prison reload locales` cannot reload them because +# these are a very low level static component of the fallback messaging system within Prison. +# You will have to restart the server if you make any changes to the messages with these prefixes. +# messages__version=4 diff --git a/prison-core/src/main/resources/lang/mines/nl_BE.properties b/prison-core/src/main/resources/lang/mines/nl_BE.properties index 921617ad9..e56e952e1 100644 --- a/prison-core/src/main/resources/lang/mines/nl_BE.properties +++ b/prison-core/src/main/resources/lang/mines/nl_BE.properties @@ -49,6 +49,15 @@ ## /prison support submit. ## +# NOTE: If you need to eliminate a message, leave an empty String after the equal sign `=`, or +# use the key word `*none*`. Prison will not insert element or send a message if +# these values are found. +# Example: `core_text__from_now=from now` use either `core_text__from_now=` or `core_text__from_now=*none*` +# +# NOTE: Specific to the `core_output__` messages, `/prison reload locales` cannot reload them because +# these are a very low level static component of the fallback messaging system within Prison. +# You will have to restart the server if you make any changes to the messages with these prefixes. +# messages__version=4 diff --git a/prison-core/src/main/resources/lang/mines/nl_NL.properties b/prison-core/src/main/resources/lang/mines/nl_NL.properties index 1013398f9..3ae2e01cb 100644 --- a/prison-core/src/main/resources/lang/mines/nl_NL.properties +++ b/prison-core/src/main/resources/lang/mines/nl_NL.properties @@ -49,6 +49,15 @@ ## /prison support submit. ## +# NOTE: If you need to eliminate a message, leave an empty String after the equal sign `=`, or +# use the key word `*none*`. Prison will not insert element or send a message if +# these values are found. +# Example: `core_text__from_now=from now` use either `core_text__from_now=` or `core_text__from_now=*none*` +# +# NOTE: Specific to the `core_output__` messages, `/prison reload locales` cannot reload them because +# these are a very low level static component of the fallback messaging system within Prison. +# You will have to restart the server if you make any changes to the messages with these prefixes. +# messages__version=4 diff --git a/prison-core/src/main/resources/lang/mines/pt_PT.properties b/prison-core/src/main/resources/lang/mines/pt_PT.properties index b1dd86d80..ede5b9ef7 100644 --- a/prison-core/src/main/resources/lang/mines/pt_PT.properties +++ b/prison-core/src/main/resources/lang/mines/pt_PT.properties @@ -49,6 +49,15 @@ ## /prison support submit. ## +# NOTE: If you need to eliminate a message, leave an empty String after the equal sign `=`, or +# use the key word `*none*`. Prison will not insert element or send a message if +# these values are found. +# Example: `core_text__from_now=from now` use either `core_text__from_now=` or `core_text__from_now=*none*` +# +# NOTE: Specific to the `core_output__` messages, `/prison reload locales` cannot reload them because +# these are a very low level static component of the fallback messaging system within Prison. +# You will have to restart the server if you make any changes to the messages with these prefixes. +# messages__version=4 diff --git a/prison-core/src/main/resources/lang/mines/ro_RO.properties b/prison-core/src/main/resources/lang/mines/ro_RO.properties index c875ef329..97432e42f 100644 --- a/prison-core/src/main/resources/lang/mines/ro_RO.properties +++ b/prison-core/src/main/resources/lang/mines/ro_RO.properties @@ -49,6 +49,15 @@ ## /prison support submit. ## +# NOTE: If you need to eliminate a message, leave an empty String after the equal sign `=`, or +# use the key word `*none*`. Prison will not insert element or send a message if +# these values are found. +# Example: `core_text__from_now=from now` use either `core_text__from_now=` or `core_text__from_now=*none*` +# +# NOTE: Specific to the `core_output__` messages, `/prison reload locales` cannot reload them because +# these are a very low level static component of the fallback messaging system within Prison. +# You will have to restart the server if you make any changes to the messages with these prefixes. +# messages__version=4 diff --git a/prison-core/src/main/resources/lang/mines/zh-CN.properties b/prison-core/src/main/resources/lang/mines/zh-CN.properties index b30302b63..29973987e 100644 --- a/prison-core/src/main/resources/lang/mines/zh-CN.properties +++ b/prison-core/src/main/resources/lang/mines/zh-CN.properties @@ -49,6 +49,15 @@ ## /prison support submit. ## +# NOTE: If you need to eliminate a message, leave an empty String after the equal sign `=`, or +# use the key word `*none*`. Prison will not insert element or send a message if +# these values are found. +# Example: `core_text__from_now=from now` use either `core_text__from_now=` or `core_text__from_now=*none*` +# +# NOTE: Specific to the `core_output__` messages, `/prison reload locales` cannot reload them because +# these are a very low level static component of the fallback messaging system within Prison. +# You will have to restart the server if you make any changes to the messages with these prefixes. +# messages__version=3 diff --git a/prison-core/src/main/resources/lang/mines/zh_TW.properties b/prison-core/src/main/resources/lang/mines/zh_TW.properties index ea87cda68..1ad538fbb 100644 --- a/prison-core/src/main/resources/lang/mines/zh_TW.properties +++ b/prison-core/src/main/resources/lang/mines/zh_TW.properties @@ -49,6 +49,15 @@ ## /prison support submit. ## +# NOTE: If you need to eliminate a message, leave an empty String after the equal sign `=`, or +# use the key word `*none*`. Prison will not insert element or send a message if +# these values are found. +# Example: `core_text__from_now=from now` use either `core_text__from_now=` or `core_text__from_now=*none*` +# +# NOTE: Specific to the `core_output__` messages, `/prison reload locales` cannot reload them because +# these are a very low level static component of the fallback messaging system within Prison. +# You will have to restart the server if you make any changes to the messages with these prefixes. +# messages__version=5 diff --git a/prison-core/src/main/resources/lang/ranks/en_US.properties b/prison-core/src/main/resources/lang/ranks/en_US.properties index ff6e18da4..5e5718ab2 100644 --- a/prison-core/src/main/resources/lang/ranks/en_US.properties +++ b/prison-core/src/main/resources/lang/ranks/en_US.properties @@ -49,6 +49,15 @@ ## /prison support submit. ## +# NOTE: If you need to eliminate a message, leave an empty String after the equal sign `=`, or +# use the key word `*none*`. Prison will not insert element or send a message if +# these values are found. +# Example: `core_text__from_now=from now` use either `core_text__from_now=` or `core_text__from_now=*none*` +# +# NOTE: Specific to the `core_output__` messages, `/prison reload locales` cannot reload them because +# these are a very low level static component of the fallback messaging system within Prison. +# You will have to restart the server if you make any changes to the messages with these prefixes. +# messages__version=28 messages__auto_refresh=true diff --git a/prison-core/src/main/resources/lang/ranks/fr_FR.properties b/prison-core/src/main/resources/lang/ranks/fr_FR.properties index 90af5af69..6f5e7f54e 100644 --- a/prison-core/src/main/resources/lang/ranks/fr_FR.properties +++ b/prison-core/src/main/resources/lang/ranks/fr_FR.properties @@ -49,6 +49,15 @@ ## /prison support submit. ## +# NOTE: If you need to eliminate a message, leave an empty String after the equal sign `=`, or +# use the key word `*none*`. Prison will not insert element or send a message if +# these values are found. +# Example: `core_text__from_now=from now` use either `core_text__from_now=` or `core_text__from_now=*none*` +# +# NOTE: Specific to the `core_output__` messages, `/prison reload locales` cannot reload them because +# these are a very low level static component of the fallback messaging system within Prison. +# You will have to restart the server if you make any changes to the messages with these prefixes. +# messages__version=28 messages__auto_refresh=true diff --git a/prison-core/src/main/resources/lang/ranks/pt_PT.properties b/prison-core/src/main/resources/lang/ranks/pt_PT.properties index 9210d41b4..c6f5ada05 100644 --- a/prison-core/src/main/resources/lang/ranks/pt_PT.properties +++ b/prison-core/src/main/resources/lang/ranks/pt_PT.properties @@ -49,6 +49,15 @@ ## /prison support submit. ## +# NOTE: If you need to eliminate a message, leave an empty String after the equal sign `=`, or +# use the key word `*none*`. Prison will not insert element or send a message if +# these values are found. +# Example: `core_text__from_now=from now` use either `core_text__from_now=` or `core_text__from_now=*none*` +# +# NOTE: Specific to the `core_output__` messages, `/prison reload locales` cannot reload them because +# these are a very low level static component of the fallback messaging system within Prison. +# You will have to restart the server if you make any changes to the messages with these prefixes. +# messages__version=6 messages__auto_refresh=true diff --git a/prison-core/src/main/resources/lang/ranks/zh-CN.properties b/prison-core/src/main/resources/lang/ranks/zh-CN.properties index 0bdc603b6..9111dfdcb 100644 --- a/prison-core/src/main/resources/lang/ranks/zh-CN.properties +++ b/prison-core/src/main/resources/lang/ranks/zh-CN.properties @@ -49,6 +49,15 @@ ## /prison support submit. ## +# NOTE: If you need to eliminate a message, leave an empty String after the equal sign `=`, or +# use the key word `*none*`. Prison will not insert element or send a message if +# these values are found. +# Example: `core_text__from_now=from now` use either `core_text__from_now=` or `core_text__from_now=*none*` +# +# NOTE: Specific to the `core_output__` messages, `/prison reload locales` cannot reload them because +# these are a very low level static component of the fallback messaging system within Prison. +# You will have to restart the server if you make any changes to the messages with these prefixes. +# messages__version=25 messages__auto_refresh=true diff --git a/prison-core/src/main/resources/lang/ranks/zh_TW.properties b/prison-core/src/main/resources/lang/ranks/zh_TW.properties index a503b64b9..88443d906 100644 --- a/prison-core/src/main/resources/lang/ranks/zh_TW.properties +++ b/prison-core/src/main/resources/lang/ranks/zh_TW.properties @@ -49,6 +49,15 @@ ## /prison support submit. ## +# NOTE: If you need to eliminate a message, leave an empty String after the equal sign `=`, or +# use the key word `*none*`. Prison will not insert element or send a message if +# these values are found. +# Example: `core_text__from_now=from now` use either `core_text__from_now=` or `core_text__from_now=*none*` +# +# NOTE: Specific to the `core_output__` messages, `/prison reload locales` cannot reload them because +# these are a very low level static component of the fallback messaging system within Prison. +# You will have to restart the server if you make any changes to the messages with these prefixes. +# messages__version=9 messages__auto_refresh=true @@ -130,7 +139,7 @@ ranks_prisonRanks__failure_loading_players=玩家資料資料失敗. %1 ranks_prisonRanks__failed_loading_players=&c無法載入玩家: %1 ranks_prisonRanks__failed_to_load_player_file=玩家資料載入失敗. %1 -ranks_prisonRanks__status_loaded_ranks=載入 %1 éšŽç´ default ranks: %2 prestige ranks: %3 other ranks: %4 +ranks_prisonRanks__status_loaded_ranks=載入 %1 階� default ranks: %2 prestige ranks: %3 other ranks: %4 ranks_prisonRanks__status_loaded_ladders=載入 %1 階 ranks_prisonRanks__status_loaded_players=載入 %1 玩家 @@ -272,8 +281,8 @@ ranks_rankCommands__rank_was_removed=階級 '%1' 已刪除æˆåŠŸ ranks_rankCommands__rank_delete_error=階級 '%1' 因出ç¾éŒ¯èª¤è€Œåˆªé™¤å¤±æ•— -ranks_rankCommands__ranks_list_header=%1 中的 éšŽç´ -šranks_rankCommands__ranks_list_ladder_cost_multplier=&3 Ladder Rank Cost Multiplier per Rank: &7%1 +ranks_rankCommands__ranks_list_header=%1 中的 階� +�ranks_rankCommands__ranks_list_ladder_cost_multplier=&3 Ladder Rank Cost Multiplier per Rank: &7%1 ranks_rankCommands__ranks_list_ladder_apply_ranks_cost_multplier=&3 Apply global Rank Cost Multipliers to this Rank? &7%1 ranks_rankCommands__ranks_list_ladder_edit_cost_multplier=Edit this Ladder's Rank Cost Multiplier. diff --git a/prison-core/src/main/resources/lang/sellall/en_US.properties b/prison-core/src/main/resources/lang/sellall/en_US.properties index 916f8cfb4..b83231b04 100644 --- a/prison-core/src/main/resources/lang/sellall/en_US.properties +++ b/prison-core/src/main/resources/lang/sellall/en_US.properties @@ -49,6 +49,16 @@ ## /prison support submit. ## +# NOTE: If you need to eliminate a message, leave an empty String after the equal sign `=`, or +# use the key word `*none*`. Prison will not insert element or send a message if +# these values are found. +# Example: `core_text__from_now=from now` use either `core_text__from_now=` or `core_text__from_now=*none*` +# +# NOTE: Specific to the `core_output__` messages, `/prison reload locales` cannot reload them because +# these are a very low level static component of the fallback messaging system within Prison. +# You will have to restart the server if you make any changes to the messages with these prefixes. +# + messages__version=2 messages__auto_refresh=true diff --git a/prison-core/src/main/resources/lang/sellall/fi_FI.properties b/prison-core/src/main/resources/lang/sellall/fi_FI.properties index bc3352c73..62ecd191f 100644 --- a/prison-core/src/main/resources/lang/sellall/fi_FI.properties +++ b/prison-core/src/main/resources/lang/sellall/fi_FI.properties @@ -49,6 +49,16 @@ ## /prison support submit. ## +# NOTE: If you need to eliminate a message, leave an empty String after the equal sign `=`, or +# use the key word `*none*`. Prison will not insert element or send a message if +# these values are found. +# Example: `core_text__from_now=from now` use either `core_text__from_now=` or `core_text__from_now=*none*` +# +# NOTE: Specific to the `core_output__` messages, `/prison reload locales` cannot reload them because +# these are a very low level static component of the fallback messaging system within Prison. +# You will have to restart the server if you make any changes to the messages with these prefixes. +# + messages__version=2 messages__auto_refresh=true @@ -58,10 +68,10 @@ sellall_function__message=&dNormaali viesti sellall_spigot_utils__money_earned=&3Tienasit &a$%1 -sellall_spigot_utils__only_sellall_signs_are_enabled=&3Voit vain myydä kylteillä, komento disabloitu. +sellall_spigot_utils__only_sellall_signs_are_enabled=&3Voit vain myyd� kylteill�, komento disabloitu. sellall_spigot_utils__rate_limit_exceeded=&3Hidasta.. -sellall_spigot_utils__shop_is_empty=&3Anteeksi, tämä myynti kauppa on tyhjä.. -sellall_spigot_utils__you_have_nothing_to_sell=&3Anteeksi, sinulla ei ole myytävää. +sellall_spigot_utils__shop_is_empty=&3Anteeksi, t�m� myynti kauppa on tyhj�.. +sellall_spigot_utils__you_have_nothing_to_sell=&3Anteeksi, sinulla ei ole myyt�v��. sellall_spigot_utils__sellall_is_disabled=&3Anteeksi, sellall on disabloitu sellall_spigot_utils__sellall_gui_is_disabled=&3Sorry, the sellall GUI is disabled.. diff --git a/prison-core/src/main/resources/lang/sellall/fr_FR.properties b/prison-core/src/main/resources/lang/sellall/fr_FR.properties index 10d609a7a..2ae8bca16 100644 --- a/prison-core/src/main/resources/lang/sellall/fr_FR.properties +++ b/prison-core/src/main/resources/lang/sellall/fr_FR.properties @@ -49,6 +49,16 @@ ## /prison support submit. ## +# NOTE: If you need to eliminate a message, leave an empty String after the equal sign `=`, or +# use the key word `*none*`. Prison will not insert element or send a message if +# these values are found. +# Example: `core_text__from_now=from now` use either `core_text__from_now=` or `core_text__from_now=*none*` +# +# NOTE: Specific to the `core_output__` messages, `/prison reload locales` cannot reload them because +# these are a very low level static component of the fallback messaging system within Prison. +# You will have to restart the server if you make any changes to the messages with these prefixes. +# + messages__version=2 messages__auto_refresh=true diff --git a/prison-core/src/main/resources/lang/sellall/pt_PT.properties b/prison-core/src/main/resources/lang/sellall/pt_PT.properties index 5fa3d2a7e..1cc23b939 100644 --- a/prison-core/src/main/resources/lang/sellall/pt_PT.properties +++ b/prison-core/src/main/resources/lang/sellall/pt_PT.properties @@ -49,6 +49,16 @@ ## /prison support submit. ## +# NOTE: If you need to eliminate a message, leave an empty String after the equal sign `=`, or +# use the key word `*none*`. Prison will not insert element or send a message if +# these values are found. +# Example: `core_text__from_now=from now` use either `core_text__from_now=` or `core_text__from_now=*none*` +# +# NOTE: Specific to the `core_output__` messages, `/prison reload locales` cannot reload them because +# these are a very low level static component of the fallback messaging system within Prison. +# You will have to restart the server if you make any changes to the messages with these prefixes. +# + messages__version=2 messages__auto_refresh=true diff --git a/prison-core/src/main/resources/lang/sellall/zh_CN.properties b/prison-core/src/main/resources/lang/sellall/zh_CN.properties index eb9e536b4..589235f44 100644 --- a/prison-core/src/main/resources/lang/sellall/zh_CN.properties +++ b/prison-core/src/main/resources/lang/sellall/zh_CN.properties @@ -49,6 +49,16 @@ ## /prison support submit. ## +# NOTE: If you need to eliminate a message, leave an empty String after the equal sign `=`, or +# use the key word `*none*`. Prison will not insert element or send a message if +# these values are found. +# Example: `core_text__from_now=from now` use either `core_text__from_now=` or `core_text__from_now=*none*` +# +# NOTE: Specific to the `core_output__` messages, `/prison reload locales` cannot reload them because +# these are a very low level static component of the fallback messaging system within Prison. +# You will have to restart the server if you make any changes to the messages with these prefixes. +# + messages__version=2 messages__auto_refresh=true diff --git a/prison-core/src/main/resources/lang/spigot/en_US.properties b/prison-core/src/main/resources/lang/spigot/en_US.properties index a53f646b3..ba94bc37f 100644 --- a/prison-core/src/main/resources/lang/spigot/en_US.properties +++ b/prison-core/src/main/resources/lang/spigot/en_US.properties @@ -49,6 +49,16 @@ ## /prison support submit. ## +# NOTE: If you need to eliminate a message, leave an empty String after the equal sign `=`, or +# use the key word `*none*`. Prison will not insert element or send a message if +# these values are found. +# Example: `core_text__from_now=from now` use either `core_text__from_now=` or `core_text__from_now=*none*` +# +# NOTE: Specific to the `core_output__` messages, `/prison reload locales` cannot reload them because +# these are a very low level static component of the fallback messaging system within Prison. +# You will have to restart the server if you make any changes to the messages with these prefixes. +# + messages__version=6 messages__auto_refresh=true diff --git a/prison-core/src/main/resources/lang/spigot/fr_FR.properties b/prison-core/src/main/resources/lang/spigot/fr_FR.properties index 3386e0a61..57a4eadbb 100644 --- a/prison-core/src/main/resources/lang/spigot/fr_FR.properties +++ b/prison-core/src/main/resources/lang/spigot/fr_FR.properties @@ -49,6 +49,16 @@ ## /prison support submit. ## +# NOTE: If you need to eliminate a message, leave an empty String after the equal sign `=`, or +# use the key word `*none*`. Prison will not insert element or send a message if +# these values are found. +# Example: `core_text__from_now=from now` use either `core_text__from_now=` or `core_text__from_now=*none*` +# +# NOTE: Specific to the `core_output__` messages, `/prison reload locales` cannot reload them because +# these are a very low level static component of the fallback messaging system within Prison. +# You will have to restart the server if you make any changes to the messages with these prefixes. +# + messages__version=6 messages__auto_refresh=true diff --git a/prison-core/src/main/resources/lang/spigot/pt_PT.properties b/prison-core/src/main/resources/lang/spigot/pt_PT.properties index 2c2272449..198f1828d 100644 --- a/prison-core/src/main/resources/lang/spigot/pt_PT.properties +++ b/prison-core/src/main/resources/lang/spigot/pt_PT.properties @@ -49,6 +49,16 @@ ## /prison support submit. ## +# NOTE: If you need to eliminate a message, leave an empty String after the equal sign `=`, or +# use the key word `*none*`. Prison will not insert element or send a message if +# these values are found. +# Example: `core_text__from_now=from now` use either `core_text__from_now=` or `core_text__from_now=*none*` +# +# NOTE: Specific to the `core_output__` messages, `/prison reload locales` cannot reload them because +# these are a very low level static component of the fallback messaging system within Prison. +# You will have to restart the server if you make any changes to the messages with these prefixes. +# + messages__version=2 messages__auto_refresh=true diff --git a/prison-core/src/main/resources/lang/spigot/zh-CN.properties b/prison-core/src/main/resources/lang/spigot/zh-CN.properties index 0f067c215..5cb478919 100644 --- a/prison-core/src/main/resources/lang/spigot/zh-CN.properties +++ b/prison-core/src/main/resources/lang/spigot/zh-CN.properties @@ -49,6 +49,16 @@ ## /prison support submit. ## +# NOTE: If you need to eliminate a message, leave an empty String after the equal sign `=`, or +# use the key word `*none*`. Prison will not insert element or send a message if +# these values are found. +# Example: `core_text__from_now=from now` use either `core_text__from_now=` or `core_text__from_now=*none*` +# +# NOTE: Specific to the `core_output__` messages, `/prison reload locales` cannot reload them because +# these are a very low level static component of the fallback messaging system within Prison. +# You will have to restart the server if you make any changes to the messages with these prefixes. +# + messages__version=5 messages__auto_refresh=true From 909afe4ca47e63c04bf9c9c2b193e9454d730b1e Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 15 Jul 2023 00:55:21 -0400 Subject: [PATCH 019/151] Update the prison API to add direct support for payPlayer function (various options). --- docs/changelog_v3.3.x.md | 3 + .../messages/SpigotVariousGuiMessages.java | 2 +- .../prison/spigot/api/PrisonSpigotAPI.java | 194 +++++++++++++++++- .../prison/spigot/sellall/SellAllUtil.java | 2 +- 4 files changed, 198 insertions(+), 3 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 985f6d37e..79a442408 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -17,6 +17,9 @@ These change logs represent the work that has been going on within prison. # 3.3.0-alpha.15 2023-07-14 +* **Update the prison API to add direct support for payPlayer function (various options).** + + * **Prison Multi-Language Locale Manager: Updated all language files to include information about the new `*none*` keyword.** This keyword is case insensitive and will return an empty string for that message component if it's part of a compound message. If the message is supposed to be sent to a player, it will be bypassed and nothing will be sent. diff --git a/prison-sellall/src/main/java/tech/mcprison/prison/sellall/messages/SpigotVariousGuiMessages.java b/prison-sellall/src/main/java/tech/mcprison/prison/sellall/messages/SpigotVariousGuiMessages.java index 479589162..0c254e71f 100644 --- a/prison-sellall/src/main/java/tech/mcprison/prison/sellall/messages/SpigotVariousGuiMessages.java +++ b/prison-sellall/src/main/java/tech/mcprison/prison/sellall/messages/SpigotVariousGuiMessages.java @@ -53,7 +53,7 @@ protected String prisonSellallTest03Msg() { } - protected String sellallAmountEarnedMsg( String earningsAmount ) { + public String sellallAmountEarnedMsg( String earningsAmount ) { return PrisonSellall.getInstance().getSellallMessages() .getLocalizable( "sellall_spigot_utils__money_earned" ) diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/api/PrisonSpigotAPI.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/api/PrisonSpigotAPI.java index c6d4a9d5b..3cb826a75 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/api/PrisonSpigotAPI.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/api/PrisonSpigotAPI.java @@ -1,5 +1,6 @@ package tech.mcprison.prison.spigot.api; +import java.text.DecimalFormat; import java.util.ArrayList; import java.util.List; import java.util.TreeMap; @@ -438,7 +439,8 @@ public double getSellAllMultiplier(Player player){ * @return BackpaacksUtil - Null if Prison Backpacks are disabled. * */ public BackpacksUtil getPrisonBackpacks(){ - if (SpigotPrison.getInstance().getConfig().getString("backpacks") != null && SpigotPrison.getInstance().getConfig().getString("backpacks").equalsIgnoreCase("true")){ + if (SpigotPrison.getInstance().getConfig().getString("backpacks") != null && + SpigotPrison.getInstance().getConfig().getString("backpacks").equalsIgnoreCase("true")){ return BackpacksUtil.get(); } return null; @@ -511,6 +513,196 @@ public Double getSellAllMoneyWithMultiplier(Player player){ return results; } + + + /** + *

This function will use Prison internals to pay a player a given sum of money as specified + * by the amount. If the currency is non-standard, then you can also specify it's name as a + * String value; otherwise pass a null or an empty String. Example of non-standard currencies + * would be alternative currencies setup on ranks. + *

+ * + *

This function will notify the player each time they are paid of the payment amount + * (notifyPlayerEarned). It will also play a payment sound (playSoundOnSellAll), the sound can + * be changed within the SellAll config file. + *

+ * + *

If you need to delay player notifications, please use the other `payPlayer()` functions. + *

+ * + *

Prison's internals keep track of the player's balance in the Prison's player cache. It + * allows for rapid payments to a player, without overwhelming Vault or the Economy plugins. + * Some economy plugins will update their database with each hit, which can result in a + * serious performance drain on the system, since such I/O is blocking, and if they run those + * updates in bukkit's main thread. Since prison is caching the payments, as soon as it + * receives a payment, prison starts a count down to make the payment. Any additional payment + * made to a player before that count down reaches zero, will be included in the transaction. + * Rapid mining can create TONS of transactions per second, so Prison's payment cache is + * an important component to help weaker economy plugins from killing the server's TPS. + *

+ * + * @param player + * @param amount + * @param currency - If standard, pass null or an empty String + */ + public void payPlayer( Player player, double amount, String currency ) { + payPlayer( player, amount, currency, true, false, false, true ); + } + + /** + *

This function will use Prison internals to pay a player a given sum of money as specified + * by the amount. This function is the same as the other one that is similar, except that it + * provides more options such as delayed notifications. Please see the help on the other + * `payPlayer()` functions to better understand what they are doing. + *

+ * + *

The payment amount must be greater than zero. If the amount is zero, or less, + * then this function will end silently without any notification. + *

+ * + *

This function has additional parameters for controlling player notifications. If they + * are all set to false, then no notifications will be sent to the player (completelySilent). + *

+ * + *

'notifyPlayerEarned': This function will notify the player each time they are paid + * of the payment amount (notifyPlayerEarned). It will also play a payment + * sound (playSoundOnSellAll), the sound can be changed within the SellAll config file. + *

+ * + *

'notifyPlayerDelay' & SellAll Delay (cooldown): If the SellAll configuration + * `isSellAllDelayEnabled` is set to `true`, then + * the player will be subjected to a cooldown for using the sellall command/feature. + * If the have tried to sell within the allocated amount of time, then they will get a + * message indicating that there is a rate limit in effect for them. They will get + * this notification if the parameter 'notifyPlayerDelay' is set to `true`. + *

+ * + *

Please NOTE: This function, `payPlayer()` only activates the cooldown timer and + * the player will be paid. What is impacted is the ability to use the functions + * `sellAllSell()`... it is then when the rate limit will kick in. If you use the + * other function `sellPlayerItems()` or `sellPlayerItemStacks()` then the + * cooldown rate limit will be bypassed and will not inhibit any selling. + *

+ * + *

'notifyPlayerEarningDelay': If in the SellAll config, the option + * `isAutoSellEarningNotificationDelayEnabled` is enabled, then this parameter + * `notifyPlayerEarningDelay` will then add the amount the player was paid to + * a delayed queue which will gather other payments the player receives during the + * delayed period. At the end of this delayed period of time, then the player + * will get a message indicating the total amount of money that they earned. + * This helps to reduce the amount of spam the player will get on line for their + * sales. Please NOTE: This does not delay the player from getting paid. If the + * delay is set to 15 seconds and they mine 100 times, they will get only one + * message with the total amount that they earned; otherwise they would have been + * sent 100 messages each time something was sold. + *

+ * + *

`playSoundOnSellAll`: If enabled, then a sound will be played upon a payment + * to the player. Please see the SellAll configuration file for changing + * the settings for the sound. + *

+ * + *

`completelySilent`: This is a virtual setting that is generated when all four + * of these settings are set to false: `notifyPlayerEarned`, `notifyPlayerDelay`, + * `notifyPlayerEarningDelay`, and `playSoundOnSellAll`. When enabled, this + * basically shuts off all notifications and the player is paid silently in the + * background. + * + * @param player + * @param amount + * @param currency + * @param notifyPlayerEarned + * @param notifyPlayerDelay + * @param notifyPlayerEarningDelay + * @param playSoundOnSellAll + */ + public void payPlayer( Player player, double amount, String currency, + boolean notifyPlayerEarned, + boolean notifyPlayerDelay, + boolean notifyPlayerEarningDelay, + boolean playSoundOnSellAll ) { + + if ( amount > 0 ) { + + boolean completelySilent = notifyPlayerEarned || notifyPlayerDelay || notifyPlayerEarningDelay || playSoundOnSellAll; + + SpigotPlayer sPlayer = new SpigotPlayer( player ); + RankPlayer rankPlayer = PrisonRanks.getInstance().getPlayerManager().getPlayer(sPlayer.getUUID(), sPlayer.getName()); + + currency = currency != null && currency.equalsIgnoreCase("default") ? null : currency; + +// if (!sellInputArrayListOnly) { +// removeSellableItems(p); +// } + rankPlayer.addBalance(currency, amount); + + if ( getPrisonSellAll().isSellAllDelayEnabled ){ + getPrisonSellAll().addToDelay(player); + } + + if (!completelySilent) { + if ( getPrisonSellAll().isSellAllSoundEnabled && playSoundOnSellAll) { + player.playSound( player.getLocation(), getPrisonSellAll().sellAllSoundSuccess, 3, 1); + } + + if (notifyPlayerEarningDelay && getPrisonSellAll().isAutoSellEarningNotificationDelayEnabled){ + if (!getPrisonSellAll().isPlayerWaitingAutoSellNotification( player )){ + getPrisonSellAll().addToAutoSellNotificationDelay( player); + } else { + getPrisonSellAll().addDelayedEarningAutoSellNotification( player, amount ); + } + } + else if (notifyPlayerEarned){ + DecimalFormat fFmt = Prison.get().getDecimalFormat("#,##0.00"); + String amt = fFmt.format( amount ); + + String message = getPrisonSellAll().sellallAmountEarnedMsg( amt ); + +// String message = messages.getString(MessagesConfig.StringID.spigot_message_sellall_money_earned) + amt; +// new SpigotPlayer(p).setActionBar( message ); + Output.get().send( sPlayer, message ); + + } + } + } + } + + + /** + *

This function will use Prison internals to pay a player a given sum of money as specified + * by the amount. This function is the same as the other ones with the same name and similar + * parameters. This one differs in that you can pass it a List of `SellAllData` transactions + * and it will summarize them all, and pass the total amount to the other + * `payPlayer()` function. Please see the help on the other + * `payPlayer()` functions to better understand what they are doing. + *

+ * + * @param player + * @param itemsSold + * @param currency + * @param notifyPlayerEarned + * @param notifyPlayerDelay + * @param notifyPlayerEarningDelay + * @param playSoundOnSellAll + */ + public void payPlayer( Player player, List itemsSold, String currency, + boolean notifyPlayerEarned, + boolean notifyPlayerDelay, + boolean notifyPlayerEarningDelay, + boolean playSoundOnSellAll ) { + double amount = 0; + + for (SellAllData item : itemsSold) { + amount += item.getTransactionAmount(); + } + + payPlayer(player, amount, currency, + notifyPlayerEarned, + notifyPlayerDelay, notifyPlayerEarningDelay, + playSoundOnSellAll); + } + + /** *

This function will calculate the value of all sellable items within the player's inventory * and provide a total amount that they earned for the sales. diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/sellall/SellAllUtil.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/sellall/SellAllUtil.java index 23b128c8b..cc2929063 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/sellall/SellAllUtil.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/sellall/SellAllUtil.java @@ -67,7 +67,7 @@ public class SellAllUtil private double defaultMultiplier; private int defaultSellAllDelay; private int defaultAutoSellEarningNotificationDelay; - private Sound sellAllSoundSuccess; + public Sound sellAllSoundSuccess; private Sound sellAllSoundFail; public String sellAllSignTag; public String sellAllCurrency; From eb6d427a39401de81ebd431dde7ea99b83ad50e2 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 15 Jul 2023 00:56:43 -0400 Subject: [PATCH 020/151] Fixed a bug with using the wrong player object within auto feature's autosell. --- docs/changelog_v3.3.x.md | 3 +++ .../prison/spigot/autofeatures/AutoManagerFeatures.java | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 79a442408..ddf14b798 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -17,6 +17,9 @@ These change logs represent the work that has been going on within prison. # 3.3.0-alpha.15 2023-07-14 +* **Fixed a bug with using the wrong player object within auto feature's autosell.** + + * **Update the prison API to add direct support for payPlayer function (various options).** diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerFeatures.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerFeatures.java index 0e86d2647..37af7dd9f 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerFeatures.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerFeatures.java @@ -891,7 +891,7 @@ protected int autoPickup( PrisonMinesBlockBreakEvent pmEvent, if ( Output.get().isDebug() && isSellallEnabled ) { // Just get the calculated value for the drops... do not sell: - double amount = SellAllUtil.get().getItemStackValue( (SpigotPlayer)player, itemStack ); + double amount = SellAllUtil.get().getItemStackValue( pmEvent.getSpigotPlayer(), itemStack ); autosellTotal += amount; debugInfo.append( "(Debug-unsold-value-check: " + itemStack.getName() + From 299c05aeac4866723a7de209d3536f207f1ac3ff Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 15 Jul 2023 01:42:47 -0400 Subject: [PATCH 021/151] Prison Tokens: bug fix: Ran in to NPE when an invalid player name is used. The message text needs to be stored in the lang files. --- docs/changelog_v3.3.x.md | 6 +++++- .../java/tech/mcprison/prison/PrisonCommand.java | 12 ++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index ddf14b798..8029a71f9 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -14,7 +14,11 @@ These change logs represent the work that has been going on within prison. -# 3.3.0-alpha.15 2023-07-14 +# 3.3.0-alpha.15 2023-07-15 + + +* **Prison Tokens: bug fix: Ran in to NPE when an invalid player name is used.** +The message text needs to be stored in the lang files. * **Fixed a bug with using the wrong player object within auto feature's autosell.** diff --git a/prison-core/src/main/java/tech/mcprison/prison/PrisonCommand.java b/prison-core/src/main/java/tech/mcprison/prison/PrisonCommand.java index 6598e41b4..c18fc525d 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/PrisonCommand.java +++ b/prison-core/src/main/java/tech/mcprison/prison/PrisonCommand.java @@ -2010,6 +2010,18 @@ public void tokensAdd( CommandSender sender, } Player player = getPlayer( playerName ); + + if ( player == null ) { + if ( !silent ) { + sender.sendMessage( + String.format( + "Prison Tokens: Player name not found. [%s] (hardCodedMessag)", + playerName )); + } + return; + } + + PlayerCachePlayerData pCache = player.getPlayerCachePlayerData(); long tokenBal = pCache.getTokens(); From 780bf47072429ad00a89556582b0c82a1512e724 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 15 Jul 2023 01:52:43 -0400 Subject: [PATCH 022/151] Prison tokens: expanded the error messages for playing not being found to the set and remove functions for the admin token commands. --- docs/changelog_v3.3.x.md | 3 +++ .../tech/mcprison/prison/PrisonCommand.java | 25 ++++++++++++++++++- 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 8029a71f9..dab21a97b 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -17,6 +17,9 @@ These change logs represent the work that has been going on within prison. # 3.3.0-alpha.15 2023-07-15 +* **Prison tokens: expanded the error messages for playing not being found to the set and remove functions for the admin token commands.** + + * **Prison Tokens: bug fix: Ran in to NPE when an invalid player name is used.** The message text needs to be stored in the lang files. diff --git a/prison-core/src/main/java/tech/mcprison/prison/PrisonCommand.java b/prison-core/src/main/java/tech/mcprison/prison/PrisonCommand.java index c18fc525d..455c3115d 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/PrisonCommand.java +++ b/prison-core/src/main/java/tech/mcprison/prison/PrisonCommand.java @@ -2015,7 +2015,7 @@ public void tokensAdd( CommandSender sender, if ( !silent ) { sender.sendMessage( String.format( - "Prison Tokens: Player name not found. [%s] (hardCodedMessag)", + "Prison Tokens add: Player name not found. [%s] (hardCodedMessag)", playerName )); } return; @@ -2121,6 +2121,18 @@ public void tokensRemove( CommandSender sender, Player player = getPlayer( playerName ); + + if ( player == null ) { + if ( !silent ) { + sender.sendMessage( + String.format( + "Prison Tokens remove: Player name not found. [%s] (hardCodedMessag)", + playerName )); + } + return; + } + + if ( forcePlayer ) { player.getPlayerCachePlayerData().removeTokens( amount ); @@ -2194,6 +2206,17 @@ public void tokensSet( CommandSender sender, // DecimalFormat dFmt = Prison.get().getDecimalFormatInt(); Player player = getPlayer( playerName ); + + + if ( player == null ) { + if ( !silent ) { + sender.sendMessage( + String.format( + "Prison Tokens set: Player name not found. [%s] (hardCodedMessag)", + playerName )); + } + return; + } // // Set to zero: // long totalTokens = player.getPlayerCachePlayerData().getTokens(); From 839ca3a8500591c05b1e86aee1db765a876538b3 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 15 Jul 2023 03:49:08 -0400 Subject: [PATCH 023/151] Auto Features AutoSell fix: There were situations where mine bombs that are set with the setting autosell was not being sold. Found a conflict with the logic of enabling autosell within the auto pickup code. There are four ways autsell could be enabled, and a couple were incorrectly mixed with their logic. Debug mode is now showing drop counts before and after adjustments from the fortune calculations. --- .../autofeatures/AutoManagerFeatures.java | 41 ++++++++++++++----- ...nagerPrisonsExplosiveBlockBreakEvents.java | 3 ++ 2 files changed, 33 insertions(+), 11 deletions(-) diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerFeatures.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerFeatures.java index 37af7dd9f..4257391c5 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerFeatures.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerFeatures.java @@ -756,7 +756,7 @@ protected int autoPickup( PrisonMinesBlockBreakEvent pmEvent, .append( amt ); if ( amt != amtBukkit ) { sItemStack.setAmount( amt ); - sb.append( "(").append( amtBukkit ).append( ")" ); + sb.append( "(bukkitAmt:").append( amtBukkit ).append( ")" ); } } if ( bukkitDropsMultiplier != 1.0d ) { @@ -765,7 +765,7 @@ protected int autoPickup( PrisonMinesBlockBreakEvent pmEvent, sb.insert( 0, "bukkitDropMult=" ); } - debugInfo.append( "[autoPickupDrops:: " ).append( sb ).append( "] "); + debugInfo.append( "[autoPickupDrops:beforeFortune:: " ).append( sb ).append( "] "); @@ -780,15 +780,24 @@ protected int autoPickup( PrisonMinesBlockBreakEvent pmEvent, // Add fortune to the items in the inventory if ( isBoolean( AutoFeatures.isCalculateFortuneEnabled ) ) { + sb.setLength(0); short fortuneLevel = getFortune(itemInHand, debugInfo ); // debugInfo.append( "(calculateFortune: fort " + fortuneLevel + ")" ); for ( SpigotItemStack itemStack : drops ) { + if ( sb.length() > 0 ) { + sb.append( "," ); + } // calculateFortune directly modifies the quantity on the blocks ItemStack: calculateFortune( itemStack, fortuneLevel, pmEvent.getDebugInfo() ); + + sb.append( itemStack.getName() ) + .append( ":" ) + .append( itemStack.getAmount() ); } + debugInfo.append( "[totalDrops:afterFortune:: " ).append( sb ).append( "] "); } @@ -840,21 +849,31 @@ protected int autoPickup( PrisonMinesBlockBreakEvent pmEvent, pmEvent.getSpigotPlayer().getWrapper() ) ; + boolean forceAutoSell = isSellallEnabled && pmEvent.isForceAutoSell(); + + boolean autoSellBySettings = isSellallEnabled && isBoolean(AutoFeatures.isAutoSellPerBlockBreakEnabled); + boolean autoSellByPerm = isSellallEnabled && + !player.isOp() && + !"disable".equalsIgnoreCase( getMessage( AutoFeatures.permissionAutoSellPerBlockBreakEnabled ) ) && + player.hasPermission( getMessage( AutoFeatures.permissionAutoSellPerBlockBreakEnabled ) ); for ( SpigotItemStack itemStack : drops ) { count += itemStack.getAmount(); - // Try to autosell if enabled: - if ( isSellallEnabled && - - (isBoolean(AutoFeatures.isAutoSellPerBlockBreakEnabled) && - isPlayerAutosellEnabled || - pmEvent.isForceAutoSell() || - !player.isOp() && !"disable".equalsIgnoreCase( getMessage( AutoFeatures.permissionAutoSellPerBlockBreakEnabled ) ) && - player.hasPermission( getMessage( AutoFeatures.permissionAutoSellPerBlockBreakEnabled ) )) && - isPlayerAutosellEnabled ) { + // Try to autosell if enabled in any of the following ways: + if ( isPlayerAutosellEnabled || forceAutoSell || autoSellBySettings || autoSellByPerm ) { + +// // Try to autosell if enabled: +// if ( isSellallEnabled && +// +// (isBoolean(AutoFeatures.isAutoSellPerBlockBreakEnabled) && +// isPlayerAutosellEnabled || +// pmEvent.isForceAutoSell() || +// !player.isOp() && !"disable".equalsIgnoreCase( getMessage( AutoFeatures.permissionAutoSellPerBlockBreakEnabled ) ) && +// player.hasPermission( getMessage( AutoFeatures.permissionAutoSellPerBlockBreakEnabled ) )) && +// isPlayerAutosellEnabled ) { final long nanoStart = System.nanoTime(); double amount = SellAllUtil.get().sellAllSell( player, itemStack, false, false, true ); diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerPrisonsExplosiveBlockBreakEvents.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerPrisonsExplosiveBlockBreakEvents.java index 64d5c0995..fdc7309fd 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerPrisonsExplosiveBlockBreakEvents.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerPrisonsExplosiveBlockBreakEvents.java @@ -321,6 +321,9 @@ protected void handleExplosiveBlockBreakEvent( ExplosiveBlockBreakEvent e, // than one. if ( e.getMineBomb() != null ) { pmEvent.setCalculateDurability( false ); + + // Set if forced autoSell: + pmEvent.setForceAutoSell( e.getMineBomb().isAutosell() ); } if ( !validateEvent( pmEvent ) ) { From 973d7efad7f21c81bc568e206fd35bc4d405598e Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 15 Jul 2023 04:00:59 -0400 Subject: [PATCH 024/151] SellAllData: The transaction log: Enhanced the itemsSoldReport by combining (compressing) entries for the same PrisonBlock type. This will make it easier to review since there will be only one entry per PrisonBlockType. --- docs/changelog_v3.3.x.md | 9 +++++ .../prison/spigot/sellall/SellAllData.java | 33 ++++++++++++++++++- 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index dab21a97b..10824af21 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -17,6 +17,15 @@ These change logs represent the work that has been going on within prison. # 3.3.0-alpha.15 2023-07-15 +* **SellAllData: The transaction log: Enhanced the itemsSoldReport by combining (compressing) entries for the same PrisonBlock type.** +This will make it easier to review since there will be only one entry per PrisonBlockType. + + +* **Auto Features AutoSell fix: There were situations where mine bombs that are set with the setting autosell was not being sold.** +Found a conflict with the logic of enabling autosell within the auto pickup code. There are four ways autsell could be enabled, and a couple were incorrectly mixed with their logic. +Debug mode is now showing drop counts before and after adjustments from the fortune calculations. + + * **Prison tokens: expanded the error messages for playing not being found to the set and remove functions for the admin token commands.** diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/sellall/SellAllData.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/sellall/SellAllData.java index cca21122a..85fe93f33 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/sellall/SellAllData.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/sellall/SellAllData.java @@ -1,6 +1,7 @@ package tech.mcprison.prison.spigot.sellall; import java.text.DecimalFormat; +import java.util.ArrayList; import java.util.List; import tech.mcprison.prison.internal.block.PrisonBlock; @@ -63,6 +64,11 @@ public static String itemsSoldReport( List soldItems, SpigotPlayer double totalAmount = 0; int itemCount = 0; + int stacks = soldItems.size(); + + // Add same blocks together: + soldItems = compressSoldItems( soldItems ); + for (SellAllData soldItem : soldItems) { if ( soldItem != null ) { @@ -85,7 +91,7 @@ public static String itemsSoldReport( List soldItems, SpigotPlayer .append( " multiplier: " ) .append( dFmt.format(multiplier) ) .append( " ItemStacks: " ) - .append( soldItems.size() ) + .append( stacks ) .append( " ItemCount: " ) .append( iFmt.format(itemCount) ) .append( " TotalAmount: " ) @@ -97,6 +103,31 @@ public static String itemsSoldReport( List soldItems, SpigotPlayer return sb.toString(); } + private static List compressSoldItems(List soldItems) { + List results = new ArrayList<>(); + + for (SellAllData sItem : soldItems) { + boolean found = false; + + for (SellAllData result : results) { + if ( sItem.getPrisonBlock().equals(result.getPrisonBlock() ) ) { + found = true; + + // found a match... add to the result item: + result.setQuantity( result.getQuantity() + sItem.getQuantity() ); + result.setTransactionAmount( result.getTransactionAmount() + sItem.getTransactionAmount() ); + break; + } + } + + if ( !found ) { + results.add(sItem); + } + } + + return results; + } + public PrisonBlock getPrisonBlock() { return prisonBlock; } From 8571c87e1fe0a4d01045941cae4e95b12d8da4f3 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 15 Jul 2023 13:59:48 -0400 Subject: [PATCH 025/151] v3.3.0-alpha.15a released on 2023-07-15 --- docs/changelog_v3.3.x.md | 5 ++++- gradle.properties | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 10824af21..be4f9b797 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -14,7 +14,10 @@ These change logs represent the work that has been going on within prison. -# 3.3.0-alpha.15 2023-07-15 +# 3.3.0-alpha.15a 2023-07-15 + + +* ** v3.3.0-alpha.15a 2023-07-15** * **SellAllData: The transaction log: Enhanced the itemsSoldReport by combining (compressing) entries for the same PrisonBlock type.** diff --git a/gradle.properties b/gradle.properties index 1e461305f..9daf50886 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,7 +3,7 @@ ## # This is actually the "correct" place to define the version for the project. ## # Used within build.gradle with ${project.version}. ## # Can be overridden on the command line: gradle -Pversion=3.2.1-alpha.3 -version=3.3.0-alpha.15 +version=3.3.0-alpha.15a From 18c6201fd1a8dbdddde85e3e7c1666e625798487 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 15 Jul 2023 14:22:27 -0400 Subject: [PATCH 026/151] Auto features not being fully disabled when turned off. There was an issue with `/prison reload autoFeatures` enabling itself when it should have been off. --- docs/changelog_v3.3.x.md | 4 ++ .../mcprison/prison/spigot/SpigotPrison.java | 1 + .../events/AutoManagerBlockBreakEvents.java | 5 ++- .../events/AutoManagerCrazyEnchants.java | 7 +++- .../events/AutoManagerPrisonEnchants.java | 7 +++- ...nagerPrisonsExplosiveBlockBreakEvents.java | 6 ++- .../AutoManagerRevEnchantsExplosiveEvent.java | 7 +++- ...AutoManagerRevEnchantsJackHammerEvent.java | 7 +++- .../events/AutoManagerTokenEnchant.java | 6 ++- .../events/AutoManagerZenchantments.java | 6 ++- .../block/OnBlockBreakEventListener.java | 37 +++++++++++++------ 11 files changed, 68 insertions(+), 25 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index be4f9b797..7298f60e5 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -17,6 +17,10 @@ These change logs represent the work that has been going on within prison. # 3.3.0-alpha.15a 2023-07-15 +* **Auto features not being fully disabled when turned off.** +There was an issue with `/prison reload autoFeatures` enabling itself when it should have been off. + + * ** v3.3.0-alpha.15a 2023-07-15** diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/SpigotPrison.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/SpigotPrison.java index 4008430ef..189db7af7 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/SpigotPrison.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/SpigotPrison.java @@ -346,6 +346,7 @@ public void onEnableStartup() { // The BlockBreakEvents must be registered after the mines and ranks modules have been enabled: + // Auto features will prevent this if it's disabled. getBlockBreakEventListeners().registerAllBlockBreakEvents( this ); diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerBlockBreakEvents.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerBlockBreakEvents.java index 55dd38947..05f0474c9 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerBlockBreakEvents.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerBlockBreakEvents.java @@ -49,7 +49,10 @@ public void setBbPriority( BlockBreakPriority bbPriority ) { @Override public void registerEvents() { - initialize(); + if ( AutoFeaturesWrapper.getInstance().isBoolean(AutoFeatures.isAutoManagerEnabled) ) { + + initialize(); + } } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerCrazyEnchants.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerCrazyEnchants.java index 7d5b598e9..0337dfa4c 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerCrazyEnchants.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerCrazyEnchants.java @@ -13,6 +13,7 @@ import org.bukkit.plugin.PluginManager; import me.badbones69.crazyenchantments.api.events.BlastUseEvent; +import tech.mcprison.prison.autofeatures.AutoFeaturesWrapper; import tech.mcprison.prison.autofeatures.AutoFeaturesFileConfig.AutoFeatures; import tech.mcprison.prison.mines.features.MineBlockEvent.BlockEventType; import tech.mcprison.prison.output.Output; @@ -56,8 +57,10 @@ public void setBbPriority( BlockBreakPriority bbPriority ) { @Override public void registerEvents() { - initialize(); - + if ( AutoFeaturesWrapper.getInstance().isBoolean(AutoFeatures.isAutoManagerEnabled) ) { + + initialize(); + } } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerPrisonEnchants.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerPrisonEnchants.java index 799113caa..6fae4927b 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerPrisonEnchants.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerPrisonEnchants.java @@ -13,6 +13,7 @@ import org.bukkit.plugin.PluginManager; import me.pulsi_.prisonenchants.events.PEExplosionEvent; +import tech.mcprison.prison.autofeatures.AutoFeaturesWrapper; import tech.mcprison.prison.autofeatures.AutoFeaturesFileConfig.AutoFeatures; import tech.mcprison.prison.mines.features.MineBlockEvent.BlockEventType; import tech.mcprison.prison.output.Output; @@ -48,8 +49,10 @@ public void setBbPriority( BlockBreakPriority bbPriority ) { @Override public void registerEvents() { - initialize(); - + if ( AutoFeaturesWrapper.getInstance().isBoolean(AutoFeatures.isAutoManagerEnabled) ) { + + initialize(); + } } /** diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerPrisonsExplosiveBlockBreakEvents.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerPrisonsExplosiveBlockBreakEvents.java index fdc7309fd..28788f1dc 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerPrisonsExplosiveBlockBreakEvents.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerPrisonsExplosiveBlockBreakEvents.java @@ -51,8 +51,10 @@ public void setBbPriority( BlockBreakPriority bbPriority ) { @Override public void registerEvents() { - initialize(); - + if ( AutoFeaturesWrapper.getInstance().isBoolean(AutoFeatures.isAutoManagerEnabled) ) { + + initialize(); + } } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerRevEnchantsExplosiveEvent.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerRevEnchantsExplosiveEvent.java index 982094061..32b49b5d0 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerRevEnchantsExplosiveEvent.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerRevEnchantsExplosiveEvent.java @@ -13,6 +13,7 @@ import org.bukkit.plugin.PluginManager; import me.revils.revenchants.events.ExplosiveEvent; +import tech.mcprison.prison.autofeatures.AutoFeaturesWrapper; import tech.mcprison.prison.autofeatures.AutoFeaturesFileConfig.AutoFeatures; import tech.mcprison.prison.mines.features.MineBlockEvent.BlockEventType; import tech.mcprison.prison.output.Output; @@ -49,8 +50,10 @@ public void setBbPriority( BlockBreakPriority bbPriority ) { @Override public void registerEvents() { - initialize(); - + if ( AutoFeaturesWrapper.getInstance().isBoolean(AutoFeatures.isAutoManagerEnabled) ) { + + initialize(); + } } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerRevEnchantsJackHammerEvent.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerRevEnchantsJackHammerEvent.java index e5c1bc2ee..8f29c41d1 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerRevEnchantsJackHammerEvent.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerRevEnchantsJackHammerEvent.java @@ -15,6 +15,7 @@ import org.bukkit.plugin.PluginManager; import me.revils.revenchants.events.JackHammerEvent; +import tech.mcprison.prison.autofeatures.AutoFeaturesWrapper; import tech.mcprison.prison.autofeatures.AutoFeaturesFileConfig.AutoFeatures; import tech.mcprison.prison.bombs.MineBombs; import tech.mcprison.prison.mines.features.MineBlockEvent.BlockEventType; @@ -54,8 +55,10 @@ public void setBbPriority( BlockBreakPriority bbPriority ) { @Override public void registerEvents() { - initialize(); - + if ( AutoFeaturesWrapper.getInstance().isBoolean(AutoFeatures.isAutoManagerEnabled) ) { + + initialize(); + } } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerTokenEnchant.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerTokenEnchant.java index 88240da24..782ca8d81 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerTokenEnchant.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerTokenEnchant.java @@ -14,6 +14,7 @@ import com.vk2gpz.tokenenchant.event.TEBlockExplodeEvent; +import tech.mcprison.prison.autofeatures.AutoFeaturesWrapper; import tech.mcprison.prison.autofeatures.AutoFeaturesFileConfig.AutoFeatures; import tech.mcprison.prison.mines.features.MineBlockEvent.BlockEventType; import tech.mcprison.prison.output.Output; @@ -53,7 +54,10 @@ public void setBbPriority( BlockBreakPriority bbPriority ) { @Override public void registerEvents() { - initialize(); + if ( AutoFeaturesWrapper.getInstance().isBoolean(AutoFeatures.isAutoManagerEnabled) ) { + + initialize(); + } } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerZenchantments.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerZenchantments.java index 15745d535..ed0f54a57 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerZenchantments.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerZenchantments.java @@ -50,8 +50,10 @@ public void setBbPriority( BlockBreakPriority bbPriority ) { @Override public void registerEvents() { - initialize(); - + if ( AutoFeaturesWrapper.getInstance().isBoolean(AutoFeatures.isAutoManagerEnabled) ) { + + initialize(); + } } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/block/OnBlockBreakEventListener.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/block/OnBlockBreakEventListener.java index d7ad293f5..095ec0d91 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/block/OnBlockBreakEventListener.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/block/OnBlockBreakEventListener.java @@ -208,29 +208,44 @@ public void reloadEventListeners() { private void registerEvents() { bbEvents = new AutoManagerBlockBreakEvents(); - bbEvents.registerEvents(); - + // Prison's own internal event and listener: pebbEvents = new AutoManagerPrisonsExplosiveBlockBreakEvents(); - pebbEvents.registerEvents(); - + + ceEvents = new AutoManagerCrazyEnchants(); + ceEvents = new AutoManagerCrazyEnchants(); - ceEvents.registerEvents(); peEvents = new AutoManagerPrisonEnchants(); - peEvents.registerEvents(); - + teEvents = new AutoManagerTokenEnchant(); - teEvents.registerEvents(); zcEvents = new AutoManagerZenchantments(); - zcEvents.registerEvents(); reEEvents = new AutoManagerRevEnchantsExplosiveEvent(); - reEEvents.registerEvents(); reJHEvents = new AutoManagerRevEnchantsJackHammerEvent(); - reJHEvents.registerEvents(); + + + if ( AutoFeaturesWrapper.getInstance().isBoolean(AutoFeatures.isAutoManagerEnabled) ) { + + bbEvents.registerEvents(); + + // Prison's own internal event and listener: + pebbEvents.registerEvents(); + + ceEvents.registerEvents(); + + peEvents.registerEvents(); + + teEvents.registerEvents(); + + zcEvents.registerEvents(); + + reEEvents.registerEvents(); + + reJHEvents.registerEvents(); + } pdBlockInspector = new PrisonDebugBlockInspector(); pdBlockInspector.init(); From eec5c89d8bae2996ab01895adab7deda11c5aaca Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sun, 16 Jul 2023 00:33:58 -0400 Subject: [PATCH 027/151] Enhance Prison's debug block inspector to fix an issue with running it multiple times for one test. Reformatted the layout so each plugin is now using only one line instead of two, and added the duration of runtime in ms. --- docs/changelog_v3.3.x.md | 9 +- .../events/PrisonDebugBlockInspector.java | 159 +++++++++++++----- .../block/OnBlockBreakEventListener.java | 4 +- 3 files changed, 130 insertions(+), 42 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 7298f60e5..87777dd97 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -21,7 +21,14 @@ These change logs represent the work that has been going on within prison. There was an issue with `/prison reload autoFeatures` enabling itself when it should have been off. -* ** v3.3.0-alpha.15a 2023-07-15** + +** v3.3.0-alpha.15a 2023-07-16** + + + + +* **Enhance Prison's debug block inspector to fix an issue with running it multiple times for one test.** +Reformatted the layout so each plugin is now using only one line instead of two, and added the duration of runtime in ms. * **SellAllData: The transaction log: Enhanced the itemsSoldReport by combining (compressing) entries for the same PrisonBlock type.** diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/PrisonDebugBlockInspector.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/PrisonDebugBlockInspector.java index 27981860d..850efb532 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/PrisonDebugBlockInspector.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/PrisonDebugBlockInspector.java @@ -1,5 +1,6 @@ package tech.mcprison.prison.spigot.autofeatures.events; +import java.text.DecimalFormat; import java.util.ArrayList; import java.util.List; @@ -27,21 +28,41 @@ public class PrisonDebugBlockInspector // extends OnBlockBreakMines { + private static PrisonDebugBlockInspector instance; + private OnBlockBreakMines obbMines; + private long lastAccess = 0; +// private boolean active = false; + public enum EventDropsStatus { normal, canceled, notSupported; } - public PrisonDebugBlockInspector() { + private PrisonDebugBlockInspector() { super(); obbMines = new OnBlockBreakMines(); + + init(); + } + + public static PrisonDebugBlockInspector getInstance() { + if ( instance == null ) { + synchronized ( PrisonDebugBlockInspector.class ) { + if ( instance == null ) { + + instance = new PrisonDebugBlockInspector(); + + } + } + } + return instance; } - public void init() { + private void init() { Prison.get().getEventBus().register(this); @@ -81,6 +102,12 @@ public void init() { @Subscribe public void onPlayerInteract( PrisonPlayerInteractEvent e ) { + // Cool down: run no sooner than every 2 seconds... prevents duplicate runs: + if ( lastAccess != 0 && (System.currentTimeMillis() - lastAccess) < 2000 ) { + return; + } + + this.lastAccess = System.currentTimeMillis(); ItemStack ourItem = e.getItemInHand(); ItemStack toolItem = SelectionManager.SELECTION_TOOL; @@ -146,20 +173,22 @@ public void onPlayerInteract( PrisonPlayerInteractEvent e ) { } else { + String message = String.format( " &3TargetBlock: &7%s " + - "&3Mined: %s%b &3Broke: &7%b", + "&3Mined: %s%b &3Broke: &7%b &3Counted: &7%b", targetBlock.getPrisonBlock().getBlockName(), (targetBlock.isMined() ? "&d" : "&2"), targetBlock.isMined(), - targetBlock.isAirBroke() + targetBlock.isAirBroke(), + targetBlock.isCounted() ); player.sendMessage( message ); Output.get().logInfo( message ); - String message2 = String.format( " &3Counted: &7%b &3Edge: &7%b " + - "&3Exploded: %s%b &3IgnoreAllEvents: &7%b", - targetBlock.isCounted(), + String message2 = String.format( " &3isEdge: &7%b " + + "&3Exploded: %s%b &3IgnoreAllEvents: &7%b", + targetBlock.isEdge(), (targetBlock.isExploded() ? "&d" : "&2"), targetBlock.isExploded(), @@ -215,6 +244,10 @@ public void onPlayerInteract( PrisonPlayerInteractEvent e ) { // // checkForEvent(e.getPlayer(), sel); // } + + // disable active prior to exiting function: + //this.active = false; + } public void dumpBlockBreakEvent( SpigotPlayer player, SpigotBlock sBlock, MineTargetPrisonBlock targetBlock ) { @@ -291,19 +324,28 @@ public void dumpBlockBreakEvent( SpigotPlayer player, SpigotBlock sBlock, MineTa tool.getName() ) ); + output.add( " &3Legend: &7EP&3: Event Priority &7EC&3: Event Canceled " + + "&7DC&3: Drops Canceled &7EB&3: Event Block &7Ds&3: Drops " + + "&7ms&3: duration in ms"); + - printEventStatus( bbe, "-initial-", "", checkBlock, targetBlock, tool, output, player ); + printEventStatus( bbe, "-initial-", "", checkBlock, targetBlock, tool, output, player, -1 ); for ( RegisteredListener listener : bbe.getHandlers().getRegisteredListeners() ) { + long start = 0; + long stop = 0; + try { // boolean isPrison = listener.getPlugin().getName().equalsIgnoreCase( "Prison" ); // boolean isSpigotListener = isPrison && listener.getListener() instanceof SpigotListener; // if ( !isSpigotListener ) { + start = System.nanoTime(); listener.callEvent( bbe ); + stop = System.nanoTime(); // } } @@ -316,9 +358,15 @@ public void dumpBlockBreakEvent( SpigotPlayer player, SpigotBlock sBlock, MineTa } + double durationNano = (stop - start); + + if ( durationNano > 0 ) { + durationNano = durationNano / 1_000_000; + } + printEventStatus( bbe, listener.getPlugin().getName(), listener.getPriority().name(), checkBlock, targetBlock, - tool, output, player ); + tool, output, player, durationNano ); } @@ -363,9 +411,11 @@ private void printEventStatus( BlockBreakEvent bbe, MineTargetPrisonBlock targetBlock, SpigotItemStack tool, List output, - SpigotPlayer player ) { + SpigotPlayer player, + double durationNano ) { StringBuilder sb = new StringBuilder(); + StringBuilder sb2 = new StringBuilder(); sb.append( " " ); boolean isCanceled = bbe.isCancelled(); @@ -386,30 +436,13 @@ else if ( isDropCanceled == EventDropsStatus.notSupported ) { bukkitDrops = obbMines.mergeDrops( bukkitDrops ); - String msg = String.format( " &3Plugin: &7%-15s &2EventPriority: &7%-9s " - + "&2EventCanceled: &7%5s &2DropsCanceled: &7%s", - plugin, - ( priority == null ? "$dnone" : priority ), - ( isCanceled ? "&4true " : "false" ), - dropStats - ); - sb.append( msg ); - - - - - output.add( sb.toString() ); - sb.setLength( 0 ); - SpigotBlock eventBlock = SpigotBlock.getSpigotBlock( bbe.getBlock() ); - - String msg2 = String.format( " &aEventBlock: &b%s ", - eventBlock == null ? - "&4none" : - eventBlock.getBlockNameFormal() ); - sb.append( msg2 ); + String eventBlockName = eventBlock == null ? + "&4none" : + eventBlock.getBlockNameFormal(); + - sb.append( " &aDrops:" ); + // Build the drops listing: if ( bukkitDrops.size() > 0 ) { // List drops = sBlk.getDrops( tool ); @@ -417,20 +450,68 @@ else if ( isDropCanceled == EventDropsStatus.notSupported ) { { // SpigotItemStack sis = (SpigotItemStack) itemStack; - sb.append( " &b" ).append( itemStack.getName() ); + sb2.append( " &b" ).append( itemStack.getName() ); if ( itemStack.getAmount() > 0 ) { - sb.append( "&a(&b" ).append( itemStack.getAmount() ).append( "&a)" ); + sb2.append( "&a(&b" ).append( itemStack.getAmount() ).append( "&a)" ); } } } else { - sb.append( "&4none" ); + sb2.append( "&4none" ); } - if ( sb.length() > 0 ) { - output.add( sb.toString() ); - sb.setLength( 0 ); - } + + DecimalFormat dFmt = new DecimalFormat("#,##0.000000"); + String durationNanoStr = durationNano == -1 ? "---" : dFmt.format( durationNano ); + + + String msg = String.format( " &3Plugin: &7%-15s &2EP: &7%-9s " + + "&2EC: &7%5s &2DC: &7%s &aEB: &b%s &aDs: %s &ams: &7%s", + plugin, + ( priority == null ? "$dnone" : priority ), + ( isCanceled ? "&4true " : "false" ), + dropStats, + eventBlockName, + sb2, + durationNanoStr + ); + sb.append( msg ); + + + output.add( sb.toString() ); + + +// sb.setLength( 0 ); + + +// String msg2 = String.format( " &aEventBlock: &b%s ", +// eventBlock == null ? +// "&4none" : +// eventBlock.getBlockNameFormal() ); +// sb.append( msg2 ); + +// sb.append( " &aDrops:" ); +// if ( bukkitDrops.size() > 0 ) { +// +//// List drops = sBlk.getDrops( tool ); +// for ( ItemStack itemStack : bukkitDrops ) +// { +//// SpigotItemStack sis = (SpigotItemStack) itemStack; +// +// sb.append( " &b" ).append( itemStack.getName() ); +// if ( itemStack.getAmount() > 0 ) { +// sb.append( "&a(&b" ).append( itemStack.getAmount() ).append( "&a)" ); +// } +// } +// } +// else { +// sb.append( "&4none" ); +// } + +// if ( sb.length() > 0 ) { +// output.add( sb.toString() ); +// sb.setLength( 0 ); +// } } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/block/OnBlockBreakEventListener.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/block/OnBlockBreakEventListener.java index 095ec0d91..a604f1b8a 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/block/OnBlockBreakEventListener.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/block/OnBlockBreakEventListener.java @@ -247,8 +247,8 @@ private void registerEvents() { reJHEvents.registerEvents(); } - pdBlockInspector = new PrisonDebugBlockInspector(); - pdBlockInspector.init(); + pdBlockInspector = PrisonDebugBlockInspector.getInstance(); +// pdBlockInspector.init(); } From 55e9f17ed39d972ac456ec2ac6a84f940e9766b6 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sun, 16 Jul 2023 01:24:17 -0400 Subject: [PATCH 028/151] More adjustments to the PrisonDebugBlockInspector for readability. --- docs/changelog_v3.3.x.md | 5 ++++- .../events/PrisonDebugBlockInspector.java | 14 ++++++++++---- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 87777dd97..9817531e0 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -14,7 +14,10 @@ These change logs represent the work that has been going on within prison. -# 3.3.0-alpha.15a 2023-07-15 +# 3.3.0-alpha.15a 2023-07-16 + + +* **More adjustments to the PrisonDebugBlockInspector for readability.** * **Auto features not being fully disabled when turned off.** diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/PrisonDebugBlockInspector.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/PrisonDebugBlockInspector.java index 850efb532..a0db0925a 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/PrisonDebugBlockInspector.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/PrisonDebugBlockInspector.java @@ -324,9 +324,15 @@ public void dumpBlockBreakEvent( SpigotPlayer player, SpigotBlock sBlock, MineTa tool.getName() ) ); - output.add( " &3Legend: &7EP&3: Event Priority &7EC&3: Event Canceled " - + "&7DC&3: Drops Canceled &7EB&3: Event Block &7Ds&3: Drops " - + "&7ms&3: duration in ms"); + + EventDropsStatus isNs = isDropCanceled( bbe ); + + + output.add( " &3Legend: &7EP&3: EventPriority &7EC&3: EventCanceled " + + "&7DC&3: DropsCanceled &7EB&3: EventBlock &7Ds&3: Drops " + + "&7ms&3: dur ms" + + ( isNs == EventDropsStatus.notSupported ? " &7NS&3: NotSupported" : "" ) + ); printEventStatus( bbe, "-initial-", "", checkBlock, targetBlock, tool, output, player, -1 ); @@ -425,7 +431,7 @@ private void printEventStatus( BlockBreakEvent bbe, dropStats = "&4" + isDropCanceled.name(); } else if ( isDropCanceled == EventDropsStatus.notSupported ) { - dropStats = "&d" + isDropCanceled.name(); + dropStats = "&dNS"; // + isDropCanceled.name(); } // Get a fresh copy of the block to ensure we pickup the latest status: From 368255784b56d831d369e56a75e17087b035c532 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sun, 16 Jul 2023 13:12:49 -0400 Subject: [PATCH 029/151] Bug fix: If a sellall transaction is null, then it now returns a zero since nothing was sold. --- docs/changelog_v3.3.x.md | 3 +++ .../java/tech/mcprison/prison/spigot/sellall/SellAllUtil.java | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 9817531e0..c3801ead4 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -17,6 +17,9 @@ These change logs represent the work that has been going on within prison. # 3.3.0-alpha.15a 2023-07-16 +* **Bug fix: If a sellall transaction is null, then it now returns a zero since nothing was sold.** + + * **More adjustments to the PrisonDebugBlockInspector for readability.** diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/sellall/SellAllUtil.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/sellall/SellAllUtil.java index cc2929063..92c957eab 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/sellall/SellAllUtil.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/sellall/SellAllUtil.java @@ -625,7 +625,7 @@ public double getItemStackValue( SpigotPlayer player, SpigotItemStack itemStack SellAllData sad = sellItemStack( itemStack, multiplier ); - return sad.getTransactionAmount(); + return sad == null ? 0 : sad.getTransactionAmount(); } public String getItemStackValueReport( SpigotPlayer sPlayer, SpigotItemStack itemStack ) { From 2a71900ab8ef59d758f16ec16b01e2d592699859 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sun, 16 Jul 2023 13:15:21 -0400 Subject: [PATCH 030/151] The Platform function getConfigStringArray should be a List of Strings for the return value, so updated the result type to reflect the correct setting. --- docs/changelog_v3.3.x.md | 3 +++ .../tech/mcprison/prison/internal/platform/Platform.java | 2 +- .../src/test/java/tech/mcprison/prison/TestPlatform.java | 2 +- .../java/tech/mcprison/prison/spigot/SpigotPlatform.java | 6 ++++-- 4 files changed, 9 insertions(+), 4 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index c3801ead4..d6fa0be98 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -17,6 +17,9 @@ These change logs represent the work that has been going on within prison. # 3.3.0-alpha.15a 2023-07-16 +* **The Platform function getConfigStringArray should be a List of Strings for the return value, so updated the result type to reflect the correct setting.** + + * **Bug fix: If a sellall transaction is null, then it now returns a zero since nothing was sold.** diff --git a/prison-core/src/main/java/tech/mcprison/prison/internal/platform/Platform.java b/prison-core/src/main/java/tech/mcprison/prison/internal/platform/Platform.java index e4479d38d..1c954dc6b 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/internal/platform/Platform.java +++ b/prison-core/src/main/java/tech/mcprison/prison/internal/platform/Platform.java @@ -444,7 +444,7 @@ public void autoCreateMineLinerAssignment( List rankMineNames, public TreeSet getExcludedWorlds(); - public List getConfigStringArray( String key ); + public List getConfigStringArray( String key ); public int compareServerVerisonTo( String comparisonVersion ); diff --git a/prison-core/src/test/java/tech/mcprison/prison/TestPlatform.java b/prison-core/src/test/java/tech/mcprison/prison/TestPlatform.java index cdef3f149..a17832b6d 100644 --- a/prison-core/src/test/java/tech/mcprison/prison/TestPlatform.java +++ b/prison-core/src/test/java/tech/mcprison/prison/TestPlatform.java @@ -295,7 +295,7 @@ public double getConfigDouble( String key, double defaultValue ) { } @Override - public List getConfigStringArray( String key ) { + public List getConfigStringArray( String key ) { return new ArrayList(); } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/SpigotPlatform.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/SpigotPlatform.java index f5b7758f5..a7c549417 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/SpigotPlatform.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/SpigotPlatform.java @@ -928,9 +928,11 @@ public String getConfigString( String key, String defaultValue ) { } + @SuppressWarnings("unchecked") @Override - public List getConfigStringArray( String key ) { - return SpigotPrison.getInstance().getConfig().getList( key, new ArrayList() ); + public List getConfigStringArray( String key ) { + return (List) SpigotPrison.getInstance().getConfig() + .getList( key, new ArrayList() ); } From 4fa8166e8431929c1d19b0eb5d65db6316035012 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sun, 16 Jul 2023 13:21:09 -0400 Subject: [PATCH 031/151] Added new feature to prevent mine bombs from being used in mines. A specific mine bomb can have a list of included mines, which overrides any exclusions. The mine bombs can be excluded from specific mines too. There is also a global disallowed mine list that will apply to all mine bombs, its in the config.yml file with the setting name of: prison-mines.mine-bombs.prevent-usage-in-mines --- docs/changelog_v3.3.x.md | 6 ++ .../mcprison/prison/bombs/MineBombData.java | 37 +++++++++++ .../tech/mcprison/prison/bombs/MineBombs.java | 62 +++++++++++++++++++ .../spigot/utils/PrisonBombListener.java | 22 +++++++ prison-spigot/src/main/resources/config.yml | 4 ++ 5 files changed, 131 insertions(+) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index d6fa0be98..45707be0b 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -17,6 +17,12 @@ These change logs represent the work that has been going on within prison. # 3.3.0-alpha.15a 2023-07-16 +* **Added new feature to prevent mine bombs from being used in mines.** +A specific mine bomb can have a list of included mines, which overrides any exclusions. The mine bombs can be excluded from specific mines too. +There is also a global disallowed mine list that will apply to all mine bombs, its in the config.yml file with the setting name of: + prison-mines.mine-bombs.prevent-usage-in-mines + + * **The Platform function getConfigStringArray should be a List of Strings for the return value, so updated the result type to reflect the correct setting.** diff --git a/prison-core/src/main/java/tech/mcprison/prison/bombs/MineBombData.java b/prison-core/src/main/java/tech/mcprison/prison/bombs/MineBombData.java index f7a41d20d..fee24d4e1 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/bombs/MineBombData.java +++ b/prison-core/src/main/java/tech/mcprison/prison/bombs/MineBombData.java @@ -179,6 +179,26 @@ public class MineBombData { private boolean autosell = false; + /** + *

This is a list of mine names where a mine bomb is allowed to be used. + * This setting overrides any global setting to disallow a specific mine, which + * allows a specific mine bomb to be used within a mine where all other + * mine bombs are excluded. + *

+ */ + private List allowedMines; + + /** + *

This is a list of mine names where this mine bomb cannot be used. + * This mine bomb specific list is combined with the global setting of + * excluded mines. The global settings is in `config.yml` and is named + * `prison-mines.mine-bombs.prevent-usage-in-mines`. + *

+ */ + private List preventedMines; + + + /** *

Internal just to indicated if a mine bomb is activated or not. * This has not purpose if used in a save file. @@ -201,6 +221,9 @@ public MineBombData() { this.soundEffects = new TreeSet<>( new MineBombEffectsData() ); this.visualEffects = new TreeSet<>( new MineBombEffectsData() ); + + this.allowedMines = new ArrayList<>(); + this.preventedMines = new ArrayList<>(); } @@ -473,6 +496,20 @@ public void setAutosell( boolean autosell ) { this.autosell = autosell; } + public List getAllowedMines() { + return allowedMines; + } + public void setAllowedMines(List allowedMines) { + this.allowedMines = allowedMines; + } + + public List getPreventedMines() { + return preventedMines; + } + public void setPreventedMines(List preventedMines) { + this.preventedMines = preventedMines; + } + public boolean isActivated() { return activated; } diff --git a/prison-core/src/main/java/tech/mcprison/prison/bombs/MineBombs.java b/prison-core/src/main/java/tech/mcprison/prison/bombs/MineBombs.java index 2f65a6392..ce3df4b73 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/bombs/MineBombs.java +++ b/prison-core/src/main/java/tech/mcprison/prison/bombs/MineBombs.java @@ -5,8 +5,10 @@ import java.util.List; import java.util.Set; +import tech.mcprison.prison.Prison; import tech.mcprison.prison.file.JsonFileIO; import tech.mcprison.prison.internal.block.PrisonBlock; +import tech.mcprison.prison.output.LogLevel; import tech.mcprison.prison.output.Output; import tech.mcprison.prison.util.Location; import tech.mcprison.prison.util.Text; @@ -355,6 +357,66 @@ public void validateMineBombs() isDirty = true; } + // map all names to lower case + if ( bomb.getAllowedMines().size() > 0 ) { + List mines = new ArrayList<>(); + boolean cleaned = false; + + for (String mineName : bomb.getAllowedMines() ) { + String cleanedMineName = mineName.toLowerCase(); + + if ( !cleanedMineName.equals( mineName ) ) { + cleaned = true; + } + + if ( !Prison.get().getPlatform().getMinesListString().contains(cleanName) ) { + Output.get().log( "MineBomb %s: invalid mine name for allowedMines: %s Removed.", + LogLevel.WARNING, + bomb.getName(), cleanedMineName ); + cleaned = true; + } + else { + + mines.add(cleanedMineName); + } + + } + if ( cleaned ) { + bomb.setAllowedMines(mines); + isDirty = true; + } + } + + // map all names to lower case + if ( bomb.getPreventedMines().size() > 0 ) { + List mines = new ArrayList<>(); + boolean cleaned = false; + + for (String mineName : bomb.getPreventedMines() ) { + String cleanedMineName = mineName.toLowerCase(); + + if ( !cleanedMineName.equals( mineName ) ) { + cleaned = true; + } + + if ( !Prison.get().getPlatform().getMinesListString().contains(cleanName) ) { + Output.get().log( "MineBomb %s: invalid mine name for prevented-Mines: %s Removed.", + LogLevel.WARNING, + bomb.getName(), cleanedMineName ); + cleaned = true; + } + else { + + mines.add(cleanedMineName); + } + + } + if ( cleaned ) { + bomb.setPreventedMines(mines); + isDirty = true; + } + } + } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/PrisonBombListener.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/PrisonBombListener.java index b1c4c6ee4..966b638fc 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/PrisonBombListener.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/PrisonBombListener.java @@ -1,5 +1,8 @@ package tech.mcprison.prison.spigot.utils; +import java.util.HashSet; +import java.util.List; + import org.bukkit.Material; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; @@ -9,6 +12,7 @@ import org.bukkit.event.player.PlayerDropItemEvent; import org.bukkit.event.player.PlayerInteractEvent; +import tech.mcprison.prison.Prison; import tech.mcprison.prison.bombs.MineBombData; import tech.mcprison.prison.bombs.MineBombs; import tech.mcprison.prison.mines.data.Mine; @@ -159,6 +163,24 @@ else if ( !mine.hasMiningAccess( sPlayer ) ) { return; } + HashSet allowedMines = new HashSet<>( bomb.getAllowedMines() ); + HashSet preventedMines = new HashSet<>( bomb.getPreventedMines() ); + List globalPreventedMines = (List) Prison.get().getPlatform() + .getConfigStringArray("prison-mines.mine-bombs.prevent-usage-in-mines"); + preventedMines.addAll( globalPreventedMines ); + + // Skip prevent-in-mines check if mine is within the allowedMines list: + if ( !allowedMines.contains( mine.getName().toLowerCase() ) ) { + + if ( preventedMines.contains( mine.getName().toLowerCase() ) ) { + + // Mine bombs are not allowed to be used in this mine so cancel: + event.setCancelled( true ); + return; + } + } + + // getHand() is not available with bukkit 1.8.8 so use the compatibility functions: EquipmentSlot hand = SpigotCompatibility.getInstance().getHand(event); // EquipmentSlot hand = event.getHand(); diff --git a/prison-spigot/src/main/resources/config.yml b/prison-spigot/src/main/resources/config.yml index 5b8f4265d..c9d9ede8a 100644 --- a/prison-spigot/src/main/resources/config.yml +++ b/prison-spigot/src/main/resources/config.yml @@ -271,6 +271,10 @@ prison-mines: access-to-prior-mines: true tp-to-spawn-on-mine-resets: true enable-suffocation-in-mines: false + mine-bombs: + prevent-usage-in-mines: + - GoldMine + - SampleMineName world-guard: region-mine: enable: true From 1652f79103db02f0bfcf45ba5144c544b7d484d6 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sun, 16 Jul 2023 13:23:52 -0400 Subject: [PATCH 032/151] Added a few more items to the default list of items in sellall. --- docs/changelog_v3.3.x.md | 3 +++ .../mcprison/prison/spigot/SpigotPlatform.java | 14 ++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 45707be0b..93ea0a199 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -17,6 +17,9 @@ These change logs represent the work that has been going on within prison. # 3.3.0-alpha.15a 2023-07-16 +* **Added a few more items to the default list of items in sellall.** + + * **Added new feature to prevent mine bombs from being used in mines.** A specific mine bomb can have a list of included mines, which overrides any exclusions. The mine bombs can be excluded from specific mines too. There is also a global disallowed mine list that will apply to all mine bombs, its in the config.yml file with the setting name of: diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/SpigotPlatform.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/SpigotPlatform.java index a7c549417..a5e37c73a 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/SpigotPlatform.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/SpigotPlatform.java @@ -2013,6 +2013,20 @@ public List buildBlockListXMaterial() { blockList.add( new SellAllBlockData( XMaterial.SUGAR, 13 ) ); blockList.add( new SellAllBlockData( XMaterial.PAPER, 13 ) ); + + blockList.add( new SellAllBlockData( XMaterial.SOUL_SAND, 25 ) ); + blockList.add( new SellAllBlockData( XMaterial.BROWN_MUSHROOM, 5 ) ); + blockList.add( new SellAllBlockData( XMaterial.BROWN_MUSHROOM_BLOCK, 5 ) ); + blockList.add( new SellAllBlockData( XMaterial.RED_MUSHROOM, 5 ) ); + blockList.add( new SellAllBlockData( XMaterial.RED_MUSHROOM_BLOCK, 5 ) ); + blockList.add( new SellAllBlockData( XMaterial.SLIME_BALL, 7 ) ); + blockList.add( new SellAllBlockData( XMaterial.SLIME_BLOCK, 63 ) ); + blockList.add( new SellAllBlockData( XMaterial.PACKED_ICE, 7 ) ); + + blockList.add( new SellAllBlockData( XMaterial.BRICK, 4 ) ); + blockList.add( new SellAllBlockData( XMaterial.BRICKS, 16 ) ); // 1 bricks = 4 brick + + return blockList; } From ed12d1a996ef3af6c85b268a09367a7de381be70 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sun, 16 Jul 2023 16:52:08 -0400 Subject: [PATCH 033/151] If at last rank, show a message to tell the player that. --- docs/changelog_v3.3.x.md | 3 +++ .../mcprison/prison/ranks/commands/RankUpCommand.java | 9 +++++++++ 2 files changed, 12 insertions(+) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 93ea0a199..e25c67ae2 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -17,6 +17,9 @@ These change logs represent the work that has been going on within prison. # 3.3.0-alpha.15a 2023-07-16 +* **If at last rank, show a message to tell the player that.** + + * **Added a few more items to the default list of items in sellall.** diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/RankUpCommand.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/RankUpCommand.java index 71abf642c..d7bb62685 100644 --- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/RankUpCommand.java +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/RankUpCommand.java @@ -455,7 +455,16 @@ private boolean rankUpPrivate(CommandSender sender, String playerName, String la RankPlayer rankPlayer = getRankPlayer( sender, player.getUUID(), player.getName() ); + + + PlayerRank rankCurrent = rankPlayer.getPlayerRank(ladder); + if ( rankCurrent.getRank().getRankNext() == null ) { + rankupAtLastRankMsg(sender); + return false; + } + // If at last rank on ladder, then cannot /rankup +// if ( rankPlayer.getran) // Get the player's next rank on default ladder, or if at end then it will return the next From aa737548b718677de3883934db5a3097a488fde7 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sun, 16 Jul 2023 16:54:18 -0400 Subject: [PATCH 034/151] PrisonPasteChat: change the exception to just Exception so it can capture all errors. The server has been down for the last two days and so other errors need to be caught. --- docs/changelog_v3.3.x.md | 4 ++++ .../java/tech/mcprison/prison/discord/PrisonPasteChat.java | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index e25c67ae2..0c2bcea3e 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -17,6 +17,10 @@ These change logs represent the work that has been going on within prison. # 3.3.0-alpha.15a 2023-07-16 +* **PrisonPasteChat: change the exception to just Exception so it can capture all errors.** +The server has been down for the last two days and so other errors need to be caught. + + * **If at last rank, show a message to tell the player that.** diff --git a/prison-core/src/main/java/tech/mcprison/prison/discord/PrisonPasteChat.java b/prison-core/src/main/java/tech/mcprison/prison/discord/PrisonPasteChat.java index a88baaed2..7d4f53db8 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/discord/PrisonPasteChat.java +++ b/prison-core/src/main/java/tech/mcprison/prison/discord/PrisonPasteChat.java @@ -249,8 +249,8 @@ private String postPaste( String text, boolean raw ) rawJson = reader.readLine(); } } - catch (IOException e) { - Output.get().logError( + catch (Exception e) { + Output.get().logWarn( String.format( "Failure in sending paste. %s ", e.getMessage()) , e ); } From fbe93d4e33547e7253b12c649a48fbc574532909 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Wed, 19 Jul 2023 11:23:45 -0400 Subject: [PATCH 035/151] Prison Support: Start to setup an alternative support file target, of an html file. This file will also convert minecraft color codes to html colors. --- docs/changelog_v3.3.x.md | 6 +- .../prison/discord/PrisonSupportFiles.java | 398 ++++++++++++++++++ .../output/SupportHyperLinkComponent.java | 23 + .../discord/PrisonSupportFilesTest.java | 49 +++ 4 files changed, 475 insertions(+), 1 deletion(-) create mode 100644 prison-core/src/main/java/tech/mcprison/prison/discord/PrisonSupportFiles.java create mode 100644 prison-core/src/main/java/tech/mcprison/prison/output/SupportHyperLinkComponent.java create mode 100644 prison-core/src/test/java/tech/mcprison/prison/discord/PrisonSupportFilesTest.java diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 0c2bcea3e..73b5c87b8 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -14,7 +14,11 @@ These change logs represent the work that has been going on within prison. -# 3.3.0-alpha.15a 2023-07-16 +# 3.3.0-alpha.15a 2023-07-19 + + +* **Prison Support: Start to setup an alternative support file target, of an html file.** +This file will also convert minecraft color codes to html colors. * **PrisonPasteChat: change the exception to just Exception so it can capture all errors.** diff --git a/prison-core/src/main/java/tech/mcprison/prison/discord/PrisonSupportFiles.java b/prison-core/src/main/java/tech/mcprison/prison/discord/PrisonSupportFiles.java new file mode 100644 index 000000000..22ca6f54d --- /dev/null +++ b/prison-core/src/main/java/tech/mcprison/prison/discord/PrisonSupportFiles.java @@ -0,0 +1,398 @@ +package tech.mcprison.prison.discord; + +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.io.StringReader; +import java.text.DecimalFormat; + +import tech.mcprison.prison.Prison; + +public class PrisonSupportFiles { + + public static final String PSFN_KEY__NAME = "{$name}"; + public static final String PSFN_KEY__NUMBER = "{$number}"; + public static final String PRISON_SUPPORT_FILE_NAME__PATTERN = "prison_support_" + + PSFN_KEY__NAME + "_" + PSFN_KEY__NUMBER + ".htm"; + + public static final String SECTION_CODE = "§"; + + private File supportFile; + + private boolean colorMapping = true; + + public enum ColorMaps { + black( "&0", "", "", ".cc0 { color: black; }"), + DarkBlue( "&1", "", "", ".cc1 { color: darkblue; }"), + DarkGreen( "&2", "", "", ".cc2 { color: darkgreen; }"), + DarkCyan( "&3", "", "", ".cc3 { color: darkCyan; }"), + DarkRed( "&4", "", "", ".cc4 { color: darkred; }"), + DarkMagenta( "&5", "", "", ".cc5 { color: darkmagenta; }"), + Orange( "&6", "", "", ".cc6 { color: orange; }"), + LightGray( "&7", "", "", ".cc7 { color: lightgray; }"), + DarkGray( "&8", "", "", ".cc8 { color: darkgray; }"), + + Blue( "&9", "", "", ".cc9 { color: blue; }"), + Green( "&a", "", "", ".cca { color: green; }"), + Cyan( "&b", "", "", ".ccb { color: cyan; }"), + Red( "&c", "", "", ".ccc { color: red[; }"), + Magenta( "&d", "", "", ".ccd { color: magenta; }"), + Yellow( "&e", "", "", ".cce { color: yellow; }"), + White( "&f", "", "", ".ccf { color: white; }"), + + + bold( "&l", "", "", null ), + strike( "&m", "", "", null ), + underline( "&n", "", "", null ), + italic( "&o", "", "", null ), + + reset( "&r", "", "", null ), + + // Internal codes: + colorMappingOff( "&-", "", "", null ), + colorMappingOn( "&+", "", "", null ) + ; + + private final String colorCode; + private final String start; + private final String end; + private final String css; + private ColorMaps( String colorCode, String start, String end, String css ) { + this.colorCode = colorCode; + this.start = start; + this.end = end; + this.css = css; + } + public String getColorCode() { + return colorCode; + } + public String getStart() { + return start; + } + public String getEnd() { + return end; + } + public String getCss() { + return css; + } + + public static ColorMaps match( String line ) { + ColorMaps results = null; + + for (ColorMaps cm : values() ) { + + String cc1 = cm.getColorCode(); + String cc2 = cc1.replace("&", SECTION_CODE); + +// char test = line.charAt(0); +// char test2 = '\u0167'; +// +// String t = "Test: " + test + test2; +// +// String cc2 = cc1.replace("&", "§"); +// String cc3 = cc1.replace("&", "\u0167"); // Section code: §, § § § +// String cc4 = cc1.replace("&", Character.toString(test2) ); +// +// char test3 = cc2.charAt(0); + +// Character.getType( cc2.charAt(0)); +// Character. ( cc2.charAt(0)); + + if ( line.toLowerCase().startsWith( cc1 ) || line.startsWith( cc2 ) ) { + results = cm; + break; + } + } + + return results; + } + } + + + public File setupSupportFile( String name ) { + + String nameId = name.replaceAll("\\s", "_"); + File file = createSupportFile( nameId ); + + setSupportFile( file ); + + return getSupportFile(); + } + + public void saveToSupportFile( StringBuilder text ) { + + File file = getSupportFile(); + + // If an empty file, then delete it: + if ( file.exists() && file.length() == 0 ) { + file.delete(); + } + + if ( !file.exists() ) { + saveSupportDataToFile( text ); + } + else { + appendSaveSupportDataToFile( text ); + } + + } + +// private void saveSupportDataToFile( StringBuilder text ) { +// File file = getSupportFile(); +// +// try { +// Files.write( text.toString().getBytes(), file); +// } +// catch (IOException e) { +// e.printStackTrace(); +// } +// } + + + private void saveSupportDataToFile( StringBuilder text ) { + File file = getSupportFile(); + + try ( + BufferedWriter bw = new BufferedWriter( new FileWriter( file, false )); // create file + ) { + + + bw.write( getGlobalCss() ); + + writeBufferedWriter( bw, text ); + + } + catch (IOException e) { + e.printStackTrace(); + } + } + + private void appendSaveSupportDataToFile( StringBuilder text ) { + File file = getSupportFile(); + + try ( + BufferedWriter bw = new BufferedWriter( new FileWriter( file, true )); // append + ) { + + bw.write( "\n\n- = - = - = - = - = - = - = - = - = - = -\n\n"); + + writeBufferedWriter( bw, text ); +// bw.write( text.toString() ); + + } + catch (IOException e) { + e.printStackTrace(); + } + } + + + private void writeBufferedWriter( BufferedWriter bw, StringBuilder text ) { + + try ( + BufferedReader br = new BufferedReader( new StringReader( text.toString() )); + ) { + + String line = br.readLine(); + + while ( line != null ) { + + String converted = convertColorCodes( line ); + + bw.write(converted); + + line = br.readLine(); + } + + } + catch ( Exception e ) { + + } + } + + + protected String convertColorCodes(String line) { + StringBuilder sb = new StringBuilder(); + + if ( isColorMapping() ) { + + StringBuilder sbEnd = new StringBuilder(); + + for ( int i = 0; i < line.length(); i++ ) { + + int idx1 = line.indexOf(SECTION_CODE, i); + int idx2 = line.indexOf("&", i); + + int idx = smallestButValid( idx1, idx2 ); + + if ( idx == -1 ) { + sb.append( line.substring(i) ); + break; + } + + String left = line.substring(i, idx); + sb.append( left ); + + String right = line.substring(idx); + ColorMaps cm = ColorMaps.match( right ); + + if ( cm == null ) { + sb.append( line.substring(idx,idx+1)); + i = idx; + } + else if ( cm == ColorMaps.colorMappingOff ) { + + setColorMapping( false ); + sb.append( right.replace( cm.getColorCode(), "" ) ); + break; + } + else if ( cm == ColorMaps.colorMappingOn ) { + + setColorMapping( true ); + sb.append( right.replace( cm.getColorCode(), "" ) ); + break; + } + else if ( cm == ColorMaps.reset ) { + sb.append( sbEnd ); + sbEnd.setLength(0); + i = idx + 1; + } + else { + sb.append( cm.getStart() ); + sbEnd.insert(0, cm.getEnd() ); + i = idx + 1; + } + } + + sb.append( sbEnd ) + .append( "
"); + } + else { + ColorMaps cm = ColorMaps.match( line ); + + // ignore all other maps... since color mapping is off, we can only search for ON: + if ( cm == ColorMaps.colorMappingOn ) { + setColorMapping( true ); + + // Return the line without the color code: + sb.append( line.replace( cm.getColorCode(), "" ) ) + .append( "
"); + } + else { + sb.append( line ) + .append( "
"); + + } + } + + return sb.toString(); + } + + private int smallestButValid(int idx1, int idx2) { + + int results = idx1 != -1 ? idx1 : -1; + + if ( results == -1 || idx2 != -1 && idx2 < results ) { + results = idx2; + } + + return results; + } + + public String getFileStats( long addedContentSize ) { + StringBuilder sb = new StringBuilder(); + + DecimalFormat dFmt = new DecimalFormat( "#,##0.000" ); + + double fileSize = getSupportFile().length() / 1024d; + + double newDataSize = addedContentSize / 1024d; + + sb.append( " * " ) + .append( getSupportFile().getAbsolutePath() ) + .append( " " ) + .append( dFmt.format(fileSize) ) + .append( " KB Added: " ) + .append( dFmt.format(newDataSize) ) + .append( " KB"); + + return sb.toString(); + } + + + private File createSupportFile( File dir, String name ) { + File file = null; + + DecimalFormat iFmt = new DecimalFormat( "0000" ); + + for ( int i = 0; i < 1000; i++ ) { + String fileName = PRISON_SUPPORT_FILE_NAME__PATTERN + .replace( PSFN_KEY__NAME, name ) + .replace( PSFN_KEY__NUMBER, iFmt.format( i ) ); + + file = new File( dir, fileName ); + if ( !file.exists() ) { + break; + } + } + return file; + } + + private File createSupportFile( String name ) { + File dir = new File( Prison.get().getDataFolder(), "backups" ); + + File file = createSupportFile( dir, name ); + +// File[] files = dir.listFiles( new FilenameFilter() { +// public boolean accept( File dir, String fileName ) { +// return fileName.startsWith("prison_support_") && +// fileName.endsWith(".md"); +// } +// }); + + return file; + } + + private String getGlobalCss() { + StringBuilder sb = new StringBuilder(); + + sb.append( "" ); + + return sb.toString(); + } + + public File getSupportFile() { + return supportFile; + } + public void setSupportFile(File supportFile) { + this.supportFile = supportFile; + } + + public boolean isColorMapping() { + return colorMapping; + } + public void setColorMapping(boolean colorMapping) { + this.colorMapping = colorMapping; + } + + +} diff --git a/prison-core/src/main/java/tech/mcprison/prison/output/SupportHyperLinkComponent.java b/prison-core/src/main/java/tech/mcprison/prison/output/SupportHyperLinkComponent.java new file mode 100644 index 000000000..0bd33f354 --- /dev/null +++ b/prison-core/src/main/java/tech/mcprison/prison/output/SupportHyperLinkComponent.java @@ -0,0 +1,23 @@ +package tech.mcprison.prison.output; + +import tech.mcprison.prison.internal.CommandSender; + +public class SupportHyperLinkComponent + extends DisplayComponent { + + protected String text; + + public SupportHyperLinkComponent(String text, Object... args) { + this.text = Output.stringFormat(text, args); + } + + @Override public String text() { + return text; + } + + @Override public void send(CommandSender sender) { + + // Do not send this message to the player... it is only for support documents: + //sender.sendMessage(text()); + } +} diff --git a/prison-core/src/test/java/tech/mcprison/prison/discord/PrisonSupportFilesTest.java b/prison-core/src/test/java/tech/mcprison/prison/discord/PrisonSupportFilesTest.java new file mode 100644 index 000000000..e058f19e1 --- /dev/null +++ b/prison-core/src/test/java/tech/mcprison/prison/discord/PrisonSupportFilesTest.java @@ -0,0 +1,49 @@ +package tech.mcprison.prison.discord; + +import static org.junit.Assert.*; + +import org.junit.Test; + +public class PrisonSupportFilesTest + extends PrisonSupportFiles +{ + + @Test + public void test() { + + String t1 = "This is a test"; + String r1 = "This is a test
"; + + assertEquals(r1, convertColorCodes(t1) ); + + + String t2 = "&3This is a test"; + String r2 = "This is a test
"; + + assertEquals(r2, convertColorCodes(t2) ); + + + String t3 = "&3This is a &1test"; + String r3 = "This is a " + + "test
"; + + assertEquals(r3, convertColorCodes(t3) ); + + + String t4 = "&3This is a &1test & sample"; + String r4 = "This is a " + + "test & sample
"; + + assertEquals(r4, convertColorCodes(t4) ); + + + String t5 = "&3This is a &1test & a&r fun &1sample"; + String r5 = "This is a " + + "test & a" + + " fun sample
"; + + assertEquals(r5, convertColorCodes(t5) ); + + } + +} From fc935b1e28a5d58b0553a41de9d275940ebf300f Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Wed, 19 Jul 2023 11:27:42 -0400 Subject: [PATCH 036/151] Prison Support: Setup the Platform with the function to get the related Rank name or Ladder name, based upon the save file's name. This is used to reverse engineer which rank or ladder is tied to a give file, without having to read the file. --- docs/changelog_v3.3.x.md | 4 +++ .../prison/internal/platform/Platform.java | 6 +++++ .../tech/mcprison/prison/TestPlatform.java | 9 +++++++ .../prison/ranks/managers/LadderManager.java | 18 ++++++++++++- .../prison/ranks/managers/RankManager.java | 13 +++++++++ .../prison/spigot/SpigotPlatform.java | 27 ++++++++++++++++++- 6 files changed, 75 insertions(+), 2 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 73b5c87b8..1579ecf3f 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -17,6 +17,10 @@ These change logs represent the work that has been going on within prison. # 3.3.0-alpha.15a 2023-07-19 +* **Prison Support: Setup the Platform with the function to get the related Rank name or Ladder name, based upon the save file's name.** +This is used to reverse engineer which rank or ladder is tied to a give file, without having to read the file. + + * **Prison Support: Start to setup an alternative support file target, of an html file.** This file will also convert minecraft color codes to html colors. diff --git a/prison-core/src/main/java/tech/mcprison/prison/internal/platform/Platform.java b/prison-core/src/main/java/tech/mcprison/prison/internal/platform/Platform.java index 1c954dc6b..3249ca241 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/internal/platform/Platform.java +++ b/prison-core/src/main/java/tech/mcprison/prison/internal/platform/Platform.java @@ -469,4 +469,10 @@ public void autoCreateMineLinerAssignment( List rankMineNames, public int getMaxY(); + + public String getLadderByFileName(String name); + + + public String getRankByFileName(String name); + } diff --git a/prison-core/src/test/java/tech/mcprison/prison/TestPlatform.java b/prison-core/src/test/java/tech/mcprison/prison/TestPlatform.java index a17832b6d..5d7b08063 100644 --- a/prison-core/src/test/java/tech/mcprison/prison/TestPlatform.java +++ b/prison-core/src/test/java/tech/mcprison/prison/TestPlatform.java @@ -546,4 +546,13 @@ public int getMinY() { public int getMaxY() { return 255; } + + public String getLadderByFileName(String name) { + return "default"; + } + + + public String getRankByFileName(String name) { + return "a"; + } } diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/managers/LadderManager.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/managers/LadderManager.java index b2613746c..f9bd31eac 100644 --- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/managers/LadderManager.java +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/managers/LadderManager.java @@ -134,9 +134,13 @@ public void saveLadder(RankLadder ladder, String fileKey) throws IOException { * @throws IOException If the ladder could not be serialized, or if the ladder could not be saved to the file. */ private void saveLadder(RankLadder ladder) throws IOException { - this.saveLadder(ladder, "ladder_" + ladder.getId()); + this.saveLadder(ladder, getLadderName(ladder)); } + private String getLadderName( RankLadder ladder ) { + return "ladder_" + ladder.getId(); + } + /** *

This is the save function that should be used from outside of the LadderManager, such as * within the LadderCommands functions because this will be able to handle the possible @@ -369,5 +373,17 @@ public String printRankLadderInfoDetail( RankLadder ladder ) { return ladderInfo; } + + public String getLadderByFileName(String fileName) { + String results = ""; + + for (RankLadder rankLadder : loadedLadders) { + String ladderFileName = getLadderName(rankLadder) + ".json"; + if ( ladderFileName.equalsIgnoreCase(fileName) ) { + results = rankLadder.getName(); + } + } + return results; + } } diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/managers/RankManager.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/managers/RankManager.java index f56f41209..38766cc23 100644 --- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/managers/RankManager.java +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/managers/RankManager.java @@ -1570,6 +1570,19 @@ public void reloadPlaceholders() { getTranslatedPlaceHolderKeys(); } + + + public String getRankByFileName(String fileName) { + String results = ""; + + for (Rank rank : loadedRanks) { + String rankFileName = rank.filename() + ".json"; + if ( rankFileName.equalsIgnoreCase(fileName) ) { + results = rank.getName(); + } + } + return results; + } private List getLoadedRanks() { return loadedRanks; diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/SpigotPlatform.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/SpigotPlatform.java index a5e37c73a..a1d599490 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/SpigotPlatform.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/SpigotPlatform.java @@ -2586,7 +2586,9 @@ else if ( !isBasic ) { } - + // REMOVE! The following will "load" the WorldGuard settings and then dump them as json to console + // to confirm they were loaded properly. Remove when done with this test1 +// new WorldGuardSettings(); } @@ -3152,4 +3154,27 @@ public int getMinY() { public int getMaxY() { return SpigotCompatibility.getInstance().getMaxY(); } + + @Override + public String getLadderByFileName(String name) { + String results = ""; + + if ( PrisonRanks.getInstance().isEnabled() ) { + results = PrisonRanks.getInstance().getLadderManager().getLadderByFileName( name ); + } + + return results; + } + + @Override + public String getRankByFileName(String name) { + String results = ""; + + if ( PrisonRanks.getInstance().isEnabled() ) { + + results = PrisonRanks.getInstance().getRankManager().getRankByFileName( name ); + } + + return results; + } } From d75233d6b8fa37b6fb4bbe944e2365a669af2fbf Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Wed, 19 Jul 2023 11:33:10 -0400 Subject: [PATCH 037/151] Prison Support: More setup of the new SupportHyperLinkComponent, but mostly the java docs which explains it pretty well. --- docs/changelog_v3.3.x.md | 2 + .../mcprison/prison/output/ChatDisplay.java | 55 ++++++++++++++++++ .../output/SupportHyperLinkComponent.java | 56 +++++++++++++++++++ 3 files changed, 113 insertions(+) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 1579ecf3f..3f00ec2da 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -16,6 +16,8 @@ These change logs represent the work that has been going on within prison. # 3.3.0-alpha.15a 2023-07-19 +* **Prison Support: More setup of the new SupportHyperLinkComponent, but mostly the java docs which explains it pretty well.** + * **Prison Support: Setup the Platform with the function to get the related Rank name or Ladder name, based upon the save file's name.** This is used to reverse engineer which rank or ladder is tied to a give file, without having to read the file. diff --git a/prison-core/src/main/java/tech/mcprison/prison/output/ChatDisplay.java b/prison-core/src/main/java/tech/mcprison/prison/output/ChatDisplay.java index 05e938e08..306300843 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/output/ChatDisplay.java +++ b/prison-core/src/main/java/tech/mcprison/prison/output/ChatDisplay.java @@ -152,5 +152,60 @@ public boolean isShowTitle() { public void setShowTitle(boolean showTitle) { this.showTitle = showTitle; } + + /** + *

This adds a hyperLink data element to the ChatDisplay. + * A hyperLink data element consist of 2 or 3 words, and no actual linkage. The hyperlinks + * will be auto generated when the support document is generated. + *

+ * + *

The proper format is for the first word to identify the major grouping, such as + * `Mine`, `Rank`, `Ladder`, or `Commands`. + *

+ * + *

The second word must be the name of the mine, rank, or ladder. For mines, ranks, and + * ladders, the second word can also be a type of groupings of such mines, rnaks, and ladders, + * such as `TOC`, `List`, etc... + * For commands, the second word must be the name of the command's config file. + *

+ * + *

The third word is used to qualify the type of item, for example for config files, the + * third world would always be `File` since it carries a special format where the contents + * do not have the color mappings rendered. Also, for some major groupings, like `Ladder List`, + * it also needs a qualifying ladder name as the third word since there are multiple + * ladders, each is a group of ranks, but there is also just a list of + * all ladders, as found in `Ladder List`. For example, `Ladder List default`, or + * `Ladder List donors`, with also `Ladder List`. + *

+ * + *

This structure is used to auto generate html tag IDs and also their related links + * to other content. + *

+ * + *

For example, let's assume we have one entry for `Rank B`. This will crate an ID for that + * section of something like `` Then it will also create hyperlinks + * to `(TOC)` `(Rank List)` `(Rank B File)`. These hyperlinks will then generat it's own ID, with + * hyperlinks to the other related content. This will allow fast and simple way to + * jump to the various components of data that is related to this concerpt of Rank B. + *

+ * + *

The data that is passed to this function should just be plain names. But the actual + * content is wrapped with double pipes. So if the data `Rank B` is passed to this function, + * it would be stored as `||Rank B||`. This notation is used to identify that it is a + * support hyperlink, so all supporting hyperlinks can be generated from this data. + *

+ * + *

This data will never be shown to players in game, or shown within the console. + * This is only included in the Prison Support documents to better utilize the + * support teams time and talents. + *

+ * + * @param linkData + */ + public void addSupportHyperLinkData( String linkData, Object... args ) { + String codedLinkData = "||" + linkData + "||"; + SupportHyperLinkComponent shlc = new SupportHyperLinkComponent( codedLinkData, args ); + addComponent( shlc ); + } } diff --git a/prison-core/src/main/java/tech/mcprison/prison/output/SupportHyperLinkComponent.java b/prison-core/src/main/java/tech/mcprison/prison/output/SupportHyperLinkComponent.java index 0bd33f354..61b938d4a 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/output/SupportHyperLinkComponent.java +++ b/prison-core/src/main/java/tech/mcprison/prison/output/SupportHyperLinkComponent.java @@ -2,6 +2,62 @@ import tech.mcprison.prison.internal.CommandSender; +/** + *

This adds a hyperLink data element to the ChatDisplay. + * A hyperLink data element consist of 2 or 3 words, and no actual linkage. The hyperlinks + * will be auto generated when the support document is generated. + *

+ * + *

This information applies to this data type, which is also part of the constructor + * with parameters. + *

+ * + *

The proper format is for the first word to identify the major grouping, such as + * `Mine`, `Rank`, `Ladder`, or `Commands`. + *

+ * + *

The second word must be the name of the mine, rank, or ladder. For mines, ranks, and + * ladders, the second word can also be a type of groupings of such mines, rnaks, and ladders, + * such as `TOC`, `List`, etc... + * For commands, the second word must be the name of the command's config file. + *

+ * + *

The third word is used to qualify the type of item, for example for config files, the + * third world would always be `File` since it carries a special format where the contents + * do not have the color mappings rendered. Also, for some major groupings, like `Ladder List`, + * it also needs a qualifying ladder name as the third word since there are multiple + * ladders, each is a group of ranks, but there is also just a list of + * all ladders, as found in `Ladder List`. For example, `Ladder List default`, or + * `Ladder List donors`, with also `Ladder List`. + *

+ * + *

This structure is used to auto generate html tag IDs and also their related links + * to other content. + *

+ * + *

For example, let's assume we have one entry for `Rank B`. This will crate an ID for that + * section of something like `` Then it will also create hyperlinks + * to `(TOC)` `(Rank List)` `(Rank B File)`. These hyperlinks will then generat it's own ID, with + * hyperlinks to the other related content. This will allow fast and simple way to + * jump to the various components of data that is related to this concerpt of Rank B. + *

+ * + *

The data that is passed to this function should just be plain names. But the actual + * content is wrapped with double pipes. So if the data `Rank B` is passed to this function, + * it would be stored as `||Rank B||`. This notation is used to identify that it is a + * support hyperlink, so all supporting hyperlinks can be generated from this data. + *

+ * + *

This data will never be shown to players in game, or shown within the console. + * This is only included in the Prison Support documents to better utilize the + * support teams time and talents. + *

+ * + * + * + * @author Blue + * + */ public class SupportHyperLinkComponent extends DisplayComponent { From 6d75b218f742b5047d96dc5294af6957b596b785 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Wed, 19 Jul 2023 12:03:51 -0400 Subject: [PATCH 038/151] Prison Support: Enabling the initial save file to an HTML file. Color codes are working great, but needs some tweaking. The framework for hyperlinks are inserted in most locations... they are just double pipes surrounding 2 or 3 words. I will generate a series of classes that will auto generate hyperlinks and table of contents based upon these encodings. --- docs/changelog_v3.3.x.md | 5 + .../tech/mcprison/prison/PrisonCommand.java | 207 +++++++++++++----- .../mcprison/prison/util/PrisonStatsUtil.java | 47 +++- .../prison/ranks/commands/LadderCommands.java | 4 + .../prison/ranks/commands/RanksCommands.java | 7 + 5 files changed, 217 insertions(+), 53 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 3f00ec2da..e64e41667 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -16,6 +16,11 @@ These change logs represent the work that has been going on within prison. # 3.3.0-alpha.15a 2023-07-19 +* **Prison Support: Enabling the initial save file to an HTML file.** +Color codes are working great, but needs some tweaking. +The framework for hyperlinks are inserted in most locations... they are just double pipes surrounding 2 or 3 words. I will generate a series of classes that will auto generate hyperlinks and table of contents based upon these encodings. + + * **Prison Support: More setup of the new SupportHyperLinkComponent, but mostly the java docs which explains it pretty well.** diff --git a/prison-core/src/main/java/tech/mcprison/prison/PrisonCommand.java b/prison-core/src/main/java/tech/mcprison/prison/PrisonCommand.java index 455c3115d..4244f4135 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/PrisonCommand.java +++ b/prison-core/src/main/java/tech/mcprison/prison/PrisonCommand.java @@ -43,6 +43,7 @@ import tech.mcprison.prison.commands.RegisteredCommand; import tech.mcprison.prison.commands.Wildcard; import tech.mcprison.prison.discord.PrisonPasteChat; +import tech.mcprison.prison.discord.PrisonSupportFiles; import tech.mcprison.prison.internal.CommandSender; import tech.mcprison.prison.internal.Player; import tech.mcprison.prison.localization.LocaleManager; @@ -73,6 +74,7 @@ public class PrisonCommand private List prisonStartupDetails; private String supportName = null; + private PrisonSupportFiles supportFile = null; private TreeMap supportURLs; @@ -1301,6 +1303,62 @@ public void supportSetName(CommandSender sender, + @Command(identifier = "prison support saveToFile", + description = "This sets the target of the support data to a local file.", + onlyPlayers = false, permissions = "prison.debug" ) + public void supportSaveToFile(CommandSender sender, + @Wildcard(join=true) + @Arg(name = "options", + description = "Enables, or disables the support file. 'basic' will enable the support file " + + "and add 'version', 'ranks', 'mines, and 'configs to the file automatically. " + + "Defaults to 'enable'. [enable, basic, disable]" ) + String options + ) { + + + if ( getSupportName() == null || getSupportName().trim().isEmpty() ) { + sender.sendMessage( "The support name needs to be set prior to using this command." ); + sender.sendMessage( "Use &7/prison support setSupportName help" ); + + return; + } + + + if ( options != null && options.toLowerCase().startsWith( "disable" ) ) { + + setSupportFile( null ); + } + else { + + setSupportFile( new PrisonSupportFiles() ); + getSupportFile().setupSupportFile( getSupportName() ); + } + + + + sender.sendMessage( String.format( "Save the support data to file: %b", + getSupportFile() != null ) ); + + if ( getSupportFile() != null ) { + sender.sendMessage( "You can now use the support submit options and they will be save to files." ); + + sender.sendMessage( " Your support save file location: " + + getSupportFile().getSupportFile().getAbsolutePath() ); + + if ( options.toLowerCase().equals( "basic" ) ) { + supportSubmitVersion(sender); + supportSubmitRanks(sender); + supportSubmitMines(sender); + supportSubmitConfigs(sender); + } + } + else { + sender.sendMessage( "Support save file has been disabled. Support files have not been removed." ); + } + } + + + @Command(identifier = "prison support submit version", description = "For Prison support: This will copy the contents of '/prison version all' " + "to paste.helpch.at so it can be easily shared with Prison's support staff .", @@ -1352,23 +1410,33 @@ public void supportSubmitVersion(CommandSender sender text.append( Output.decodePercentEncoding(log) ).append( "\n" ); } + if ( getSupportFile() != null ) { + + getSupportFile().saveToSupportFile( text ); + + sender.sendMessage(" - Support 'version' data was just added to the support output file." ); + sender.sendMessage( getSupportFile().getFileStats( text.length() ) ); + } + else { + + PrisonPasteChat pasteChat = new PrisonPasteChat( getSupportName(), getSupportURLs() ); + + String helpURL = pasteChat.post( text.toString() ); + + getSupportURLs().put( "Submit version:", helpURL ); + + if ( helpURL != null ) { + + sender.sendMessage( "Prison's support information has been pasted. Copy and " + + "paste this URL in to Prison's Discord server." ); + sender.sendMessage( String.format( "Paste this URL: %s", helpURL )); + } + else { + sender.sendMessage( "There was an error trying to generate the paste.helpch.at URL." ); + } + + } - PrisonPasteChat pasteChat = new PrisonPasteChat( getSupportName(), getSupportURLs() ); - - String helpURL = pasteChat.post( text.toString() ); - - getSupportURLs().put( "Submit version:", helpURL ); - - if ( helpURL != null ) { - - sender.sendMessage( "Prison's support information has been pasted. Copy and " + - "paste this URL in to Prison's Discord server." ); - sender.sendMessage( String.format( "Paste this URL: %s", helpURL )); - } - else { - sender.sendMessage( "There was an error trying to generate the paste.helpch.at URL." ); - } - } @@ -1394,24 +1462,34 @@ public void supportSubmitConfigs(CommandSender sender StringBuilder text = Prison.get().getPrisonStatsUtil().getSupportSubmitConfigsData(); - - PrisonPasteChat pasteChat = new PrisonPasteChat( getSupportName(), getSupportURLs() ); - String helpURL = pasteChat.postKeepColorCodes( text.toString() ); - getSupportURLs().put( "Submit configs:", helpURL ); - - if ( helpURL != null ) { + if ( getSupportFile() != null ) { - sender.sendMessage( "Prison's support information has been pasted. Copy and " + - "paste this URL in to Prison's Discord server." ); - sender.sendMessage( String.format( "Paste this URL: %s", helpURL )); + getSupportFile().saveToSupportFile( text ); + + sender.sendMessage(" - Support 'configs' data was just added to the support output file." ); + sender.sendMessage( getSupportFile().getFileStats( text.length() ) ); } else { - sender.sendMessage( "There was an error trying to generate the paste.helpch.at URL." ); + + PrisonPasteChat pasteChat = new PrisonPasteChat( getSupportName(), getSupportURLs() ); + + String helpURL = pasteChat.postKeepColorCodes( text.toString() ); + + getSupportURLs().put( "Submit configs:", helpURL ); + + if ( helpURL != null ) { + + sender.sendMessage( "Prison's support information has been pasted. Copy and " + + "paste this URL in to Prison's Discord server." ); + sender.sendMessage( String.format( "Paste this URL: %s", helpURL )); + } + else { + sender.sendMessage( "There was an error trying to generate the paste.helpch.at URL." ); + } + } - - } @@ -1435,23 +1513,32 @@ public void supportSubmitRanks(CommandSender sender StringBuilder text = Prison.get().getPrisonStatsUtil().getSupportSubmitRanksData(); - PrisonPasteChat pasteChat = new PrisonPasteChat( getSupportName(), getSupportURLs() ); - - String helpURL = pasteChat.post( text.toString() ); - - getSupportURLs().put( "Submit ranks:", helpURL ); - - if ( helpURL != null ) { + if ( getSupportFile() != null ) { - sender.sendMessage( "Prison's support information has been pasted. Copy and " + - "paste this URL in to Prison's Discord server." ); - sender.sendMessage( String.format( "Paste this URL: %s", helpURL )); + getSupportFile().saveToSupportFile( text ); + + sender.sendMessage(" - Support 'ranks' data was just added to the support output file." ); + sender.sendMessage( getSupportFile().getFileStats( text.length() ) ); } else { - sender.sendMessage( "There was an error trying to generate the paste.helpch.at URL." ); + + PrisonPasteChat pasteChat = new PrisonPasteChat( getSupportName(), getSupportURLs() ); + + String helpURL = pasteChat.post( text.toString() ); + + getSupportURLs().put( "Submit ranks:", helpURL ); + + if ( helpURL != null ) { + + sender.sendMessage( "Prison's support information has been pasted. Copy and " + + "paste this URL in to Prison's Discord server." ); + sender.sendMessage( String.format( "Paste this URL: %s", helpURL )); + } + else { + sender.sendMessage( "There was an error trying to generate the paste.helpch.at URL." ); + } } - } @@ -1476,23 +1563,32 @@ public void supportSubmitMines(CommandSender sender StringBuilder text = Prison.get().getPrisonStatsUtil().getSupportSubmitMinesData(); - PrisonPasteChat pasteChat = new PrisonPasteChat( getSupportName(), getSupportURLs() ); - - String helpURL = pasteChat.post( text.toString() ); - - getSupportURLs().put( "Submit mines:", helpURL ); - - if ( helpURL != null ) { + if ( getSupportFile() != null ) { - sender.sendMessage( "Prison's support information has been pasted. Copy and " + - "paste this URL in to Prison's Discord server." ); - sender.sendMessage( String.format( "Paste this URL: %s", helpURL )); + getSupportFile().saveToSupportFile( text ); + + sender.sendMessage(" - Support 'mines' data was just added to the support output file." ); + sender.sendMessage( getSupportFile().getFileStats( text.length() ) ); } else { - sender.sendMessage( "There was an error trying to generate the paste.helpch.at URL." ); + + PrisonPasteChat pasteChat = new PrisonPasteChat( getSupportName(), getSupportURLs() ); + + String helpURL = pasteChat.post( text.toString() ); + + getSupportURLs().put( "Submit mines:", helpURL ); + + if ( helpURL != null ) { + + sender.sendMessage( "Prison's support information has been pasted. Copy and " + + "paste this URL in to Prison's Discord server." ); + sender.sendMessage( String.format( "Paste this URL: %s", helpURL )); + } + else { + sender.sendMessage( "There was an error trying to generate the paste.helpch.at URL." ); + } } - } @@ -2333,6 +2429,13 @@ public void setSupportName( String supportName ) { this.supportName = supportName; } + public PrisonSupportFiles getSupportFile() { + return supportFile; + } + public void setSupportFile(PrisonSupportFiles supportFile) { + this.supportFile = supportFile; + } + public TreeMap getSupportURLs() { return supportURLs; } diff --git a/prison-core/src/main/java/tech/mcprison/prison/util/PrisonStatsUtil.java b/prison-core/src/main/java/tech/mcprison/prison/util/PrisonStatsUtil.java index 56857746c..6267c2f0a 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/util/PrisonStatsUtil.java +++ b/prison-core/src/main/java/tech/mcprison/prison/util/PrisonStatsUtil.java @@ -223,11 +223,54 @@ private void addFileToText(File file, StringBuilder sb) { DecimalFormat dFmt = Prison.get().getDecimalFormatInt(); SimpleDateFormat sdFmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + + String parentDirName = file.getParentFile().getName(); + + String header = ""; + String name = ""; + + if ( "ranks".equalsIgnoreCase(parentDirName) ) { + // Rank file names have a prefix of "ranks_" and then the rankId, followed by the suffix. + // Need to use the rankId to find the rank's name: + + header = "Rank"; + name = Prison.get().getPlatform().getRankByFileName( file.getName() ); + } + else if ( "ladders".equalsIgnoreCase(parentDirName) ) { + // Ladder file names have a prefix of "ladders_" and then the ladderId, followed by the suffix. + // Need to use the ladderId to find the ladder's name: + + header = "Ladder"; + name = Prison.get().getPlatform().getLadderByFileName( file.getName() ); + } + else if ( "mines".equalsIgnoreCase(parentDirName) ) { + // The file name of the mine, minus the suffix, is the name's name. + + header = "Mine"; + name = file.getName().replace(".json", ""); + } + else { + header = "Config"; + name = file.getName(); + } + + sb.append("\n"); JumboTextFont.makeJumboFontText(file.getName(), sb); sb.append("\n"); + + + // Hyper Link codes: + sb.append( "||" ) + .append( header ) + .append( " " ) + .append( name ) + .append( " " ) + .append( "File" ) + .append( "||\n" ); + sb.append("File Name: ").append(file.getName()).append("\n"); sb.append("File Path: ").append(file.getAbsolutePath()).append("\n"); @@ -241,7 +284,9 @@ private void addFileToText(File file, StringBuilder sb) { sb.append("\n"); if (file.exists() && file.canRead()) { + sb.append("&-"); readFileToStringBulider(file, sb); + sb.append("\n&+"); } else { sb.append("Warning: The file is not readable so it cannot be included.\n"); } @@ -251,7 +296,7 @@ private void addFileToText(File file, StringBuilder sb) { public void printFooter(StringBuilder sb) { - sb.append("\n\n\n"); + sb.append("\n\n"); sb.append("=== --- === --- === --- === --- === --- ===\n"); sb.append("=== # # ### # # # ### # # # ### # # # ### # # # ### # # ===\n"); sb.append("=== --- === --- === --- === --- === --- ===\n"); diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/LadderCommands.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/LadderCommands.java index 4e166ba48..f1f42181c 100644 --- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/LadderCommands.java +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/LadderCommands.java @@ -96,6 +96,10 @@ public void ladderRemove(CommandSender sender, @Arg(name = "ladderName") String public void ladderList(CommandSender sender) { ChatDisplay display = new ChatDisplay("Ladders"); + + display.addSupportHyperLinkData( "Ladder List" ); + + BulletedListComponent.BulletedListBuilder list = new BulletedListComponent.BulletedListBuilder(); diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/RanksCommands.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/RanksCommands.java index 47b28ea24..651155a9e 100644 --- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/RanksCommands.java +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/RanksCommands.java @@ -676,6 +676,8 @@ public void listRanks(CommandSender sender, else { display = new ChatDisplay( "List ALL Ranks" ); + display.addSupportHyperLinkData( "Rank List" ); + listAllRanksByLadders( display, hasPerm, rPlayer ); } @@ -836,6 +838,8 @@ private ChatDisplay listRanksOnLadder( RankLadder ladder, boolean hasPerm, RankP String rankHeader = ranksListHeaderMsg( ladder.getName() ); ChatDisplay display = new ChatDisplay( rankHeader ); + display.addSupportHyperLinkData( "Ladder List %s", ladder.getName() ); + display.addText( " " + PrisonRanks.getInstance().getLadderManager().printRankLadderInfoHeader() ); display.addText( " " + PrisonRanks.getInstance().getLadderManager().printRankLadderInfoDetail(ladder) ); @@ -1161,6 +1165,9 @@ private ChatDisplay rankInfoDetails( CommandSender sender, Rank rank, String opt ChatDisplay display = new ChatDisplay( ranksInfoHeaderMsg( title )); + display.addSupportHyperLinkData( "Rank %s", rank.getName() ); + + boolean isOp = sender != null && sender.isOp(); boolean isConsole = sender == null || !sender.isPlayer(); From 65b9ae2c30419eb009a095d117a47c820c0c9894 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Wed, 19 Jul 2023 21:39:44 -0400 Subject: [PATCH 039/151] Prison Support: More enhancements to the html save file. Instead of calling the four `/prison support submit` commands, they are all now generated from within the same function. This will allow the collection of all hyperlinks to generate a tabl of contents. Improvements to the layout of some of the items in report. --- docs/changelog_v3.3.x.md | 6 + .../tech/mcprison/prison/PrisonCommand.java | 61 ++-- .../prison/discord/PrisonSupportFiles.java | 2 +- .../mcprison/prison/util/PrisonStatsUtil.java | 267 ++++++++++++++++-- .../prison/mines/commands/MinesCommands.java | 2 + .../prison/ranks/commands/LadderCommands.java | 56 +++- .../prison/spigot/SpigotPlatform.java | 27 +- 7 files changed, 369 insertions(+), 52 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index e64e41667..4e158ea17 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -16,6 +16,12 @@ These change logs represent the work that has been going on within prison. # 3.3.0-alpha.15a 2023-07-19 + +* **Prison Support: More enhancements to the html save file.** +Instead of calling the four `/prison support submit` commands, they are all now generated from within the same function. This will allow the collection of all hyperlinks to generate a tabl of contents. +Improvements to the layout of some of the items in report. + + * **Prison Support: Enabling the initial save file to an HTML file.** Color codes are working great, but needs some tweaking. The framework for hyperlinks are inserted in most locations... they are just double pipes surrounding 2 or 3 words. I will generate a series of classes that will auto generate hyperlinks and table of contents based upon these encodings. diff --git a/prison-core/src/main/java/tech/mcprison/prison/PrisonCommand.java b/prison-core/src/main/java/tech/mcprison/prison/PrisonCommand.java index 4244f4135..aa1e49c5c 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/PrisonCommand.java +++ b/prison-core/src/main/java/tech/mcprison/prison/PrisonCommand.java @@ -1346,10 +1346,19 @@ public void supportSaveToFile(CommandSender sender, getSupportFile().getSupportFile().getAbsolutePath() ); if ( options.toLowerCase().equals( "basic" ) ) { - supportSubmitVersion(sender); - supportSubmitRanks(sender); - supportSubmitMines(sender); - supportSubmitConfigs(sender); + + StringBuilder text = Prison.get().getPrisonStatsUtil().getSupportSubmitBasic(); + + getSupportFile().saveToSupportFile( text ); + + sender.sendMessage(" - Support 'basic' data was just added to the support output file." ); + sender.sendMessage(" - Includes: version, listeners, command stats, ladders, Ranks, Mines, and all Config files." ); + sender.sendMessage( getSupportFile().getFileStats( text.length() ) ); + +// supportSubmitVersion(sender); +// supportSubmitRanks(sender); +// supportSubmitMines(sender); +// supportSubmitConfigs(sender); } } else { @@ -1393,22 +1402,27 @@ public void supportSubmitVersion(CommandSender sender ); // Include the command stats: - text.append( "\n\n" ); - List cmdStats = getCommandStats(); - for (String cmd : cmdStats) { - text.append( cmd ).append( "\n" ); - } + text.append( Prison.get().getPrisonStatsUtil().getCommandStatsDetailData() ); +// text.append( "\n\n" ); +// List cmdStats = getCommandStats(); +// for (String cmd : cmdStats) { +// text.append( cmd ).append( "\n" ); +// } // Include Prison backup logs: - text.append( "\n\n" ); - text.append( "Prison Backup Logs:" ).append( "\n" ); - List backupLogs = getPrisonBackupLogs(); + text.append( Prison.get().getPrisonStatsUtil().getPrisonBackupLogsData() ); +// text.append( "\n\n" ); +// text.append( "Prison Backup Logs:" ).append( "\n" ); +// List backupLogs = getPrisonBackupLogs(); +// +// for (String log : backupLogs) { +// text.append( Output.decodePercentEncoding(log) ).append( "\n" ); +// } + + - for (String log : backupLogs) { - text.append( Output.decodePercentEncoding(log) ).append( "\n" ); - } if ( getSupportFile() != null ) { @@ -1510,8 +1524,12 @@ public void supportSubmitRanks(CommandSender sender } + // List Ladder and rank lists: StringBuilder text = Prison.get().getPrisonStatsUtil().getSupportSubmitRanksData(); + // List rank files: + text.append( Prison.get().getPrisonStatsUtil().getSupportSubmitRanksFileData() ); + if ( getSupportFile() != null ) { @@ -1978,7 +1996,8 @@ public void supportBackupList( CommandSender sender ) { ChatDisplay display = new ChatDisplay("Prison Backup Logs:"); - List backupLogs = getPrisonBackupLogs(); + List backupLogs = Prison.get().getPrisonStatsUtil().getPrisonBackupLogs(); +// List backupLogs = getPrisonBackupLogs(); for (String log : backupLogs) { display.addText(log); @@ -1988,11 +2007,11 @@ public void supportBackupList( CommandSender sender ) { } - private List getPrisonBackupLogs() { - PrisonBackups prisonBackup = new PrisonBackups(); - List backupLogs = prisonBackup.backupReport02BackupLog(); - return backupLogs; - } +// private List getPrisonBackupLogs() { +// PrisonBackups prisonBackup = new PrisonBackups(); +// List backupLogs = prisonBackup.backupReport02BackupLog(); +// return backupLogs; +// } @Command(identifier = "prison tokens balance", diff --git a/prison-core/src/main/java/tech/mcprison/prison/discord/PrisonSupportFiles.java b/prison-core/src/main/java/tech/mcprison/prison/discord/PrisonSupportFiles.java index 22ca6f54d..7783a469d 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/discord/PrisonSupportFiles.java +++ b/prison-core/src/main/java/tech/mcprison/prison/discord/PrisonSupportFiles.java @@ -313,7 +313,7 @@ public String getFileStats( long addedContentSize ) { .append( getSupportFile().getAbsolutePath() ) .append( " " ) .append( dFmt.format(fileSize) ) - .append( " KB Added: " ) + .append( " KB Before HTML conversion: " ) .append( dFmt.format(newDataSize) ) .append( " KB"); diff --git a/prison-core/src/main/java/tech/mcprison/prison/util/PrisonStatsUtil.java b/prison-core/src/main/java/tech/mcprison/prison/util/PrisonStatsUtil.java index 6267c2f0a..d7f0f2599 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/util/PrisonStatsUtil.java +++ b/prison-core/src/main/java/tech/mcprison/prison/util/PrisonStatsUtil.java @@ -10,14 +10,100 @@ import java.util.Collections; import java.util.Date; import java.util.List; +import java.util.TreeSet; import tech.mcprison.prison.Prison; +import tech.mcprison.prison.backups.PrisonBackups; +import tech.mcprison.prison.commands.RegisteredCommand; import tech.mcprison.prison.discord.PrisonPasteChat; import tech.mcprison.prison.file.JsonFileIO; import tech.mcprison.prison.output.ChatDisplay; import tech.mcprison.prison.output.Output; public class PrisonStatsUtil { + + + /** + *

This will return in a StringBuilder all of the information from the following + * commands. They will be combined in one large StringBuilder object so a table of + * contents can be built from it. This is similar to running the following 4 + * commands, but are better organized with the order of the details (files last). + *

+ * + *
/prison support submit version
+ *
/prison support submit ranks
+ *
/prison support submit mines
+ *
/prison support submit commands
+ * + *

The difference with this function, is that all of the raw files are + * included at the end, instead of being mixed in with the other non-raw file + * dumps. + *

+ * + *

Order of reports:

+ *
    + *
  • Version ALL
  • + *
  • listeners ALL
  • + *
  • Command Stats
  • + * + *
  • Ladder List - Missing?
  • + *
  • Rank List
  • + *
  • Rank details
  • + * + *
  • Mine List
  • + *
  • Mine details
  • + * + *
  • Prison Backup Files
  • + + *
  • Ladder Files
  • + *
  • Rank Files
  • + * + *
  • Mine Files
  • + * + *
  • ConfigSettings Files
  • + * + *
+ * + * @return + */ + public StringBuilder getSupportSubmitBasic() { + StringBuilder sb = new StringBuilder(); + + // version info: + sb.append( getSupportSubmitVersionData() ); + + // Listeners: + sb.append( getSupportSubmitListenersData( "all" ) ); + + // Command Stats: + sb.append( getCommandStatsDetailData() ); + + + // Rank Lists and Rank details: + sb.append( getSupportSubmitRanksData() ); + + + // Mine lists and Mine details: + sb.append( getSupportSubmitMinesData() ); + + + // Backup log files: + sb.append( getPrisonBackupLogsData() ); + + + // Rank Files: + sb.append( getSupportSubmitRanksFileData() ); + + + // Mine files: + sb.append( getSupportSubmitMinesFileData() ); + + + // Config files: + sb.append( getSupportSubmitConfigsData() ); + + return sb; + } public ChatDisplay displayVersion(String options) { @@ -102,14 +188,30 @@ public void copyConfigsFiles() { } - + public StringBuilder getSupportSubmitRanksData() { + + StringBuilder text = new StringBuilder(); + + text.append(Prison.get().getPlatform().getRanksListString()); + printFooter(text); + +// List files = listFiles("data_storage/ranksDb/ladders/", ".json"); +// files.addAll(listFiles("data_storage/ranksDb/ranks/", ".json")); +// for (File file : files) { +// +// addFileToText(file, text); +// } + + return text; + } + + public StringBuilder getSupportSubmitRanksFileData() { List files = listFiles("data_storage/ranksDb/ladders/", ".json"); files.addAll(listFiles("data_storage/ranksDb/ranks/", ".json")); StringBuilder text = new StringBuilder(); - text.append(Prison.get().getPlatform().getRanksListString()); printFooter(text); for (File file : files) { @@ -121,28 +223,46 @@ public StringBuilder getSupportSubmitRanksData() { } public StringBuilder getSupportSubmitMinesData() { - List files = listFiles("data_storage/mines/mines/", ".json"); - Collections.sort(files); +// List files = listFiles("data_storage/mines/mines/", ".json"); +// Collections.sort(files); StringBuilder text = new StringBuilder(); - text.append("\n"); - text.append("Table of contents:\n"); - text.append(" 1. Mine list - All mines including virtual mines: /mines list all\n"); - text.append(" 2. Mine info - All mines: /mines info all\n"); - text.append(" 3. Mine files - Raw JSON dump of all mine configuration files.\n"); - text.append("\n"); +// text.append("\n"); +// text.append("Table of contents:\n"); +// text.append(" 1. Mine list - All mines including virtual mines: /mines list all\n"); +// text.append(" 2. Mine info - All mines: /mines info all\n"); +// text.append(" 3. Mine files - Raw JSON dump of all mine configuration files.\n"); +// text.append("\n"); // Display a list of all mines, then display the /mines info all for // each: text.append(Prison.get().getPlatform().getMinesListString()); - printFooter(text); +// printFooter(text); +// // get all the file details for each mine: +// for (File file : files) { +// +// addFileToText(file, text); +// } + + return text; + } + + public StringBuilder getSupportSubmitMinesFileData() { + List files = listFiles("data_storage/mines/mines/", ".json"); + Collections.sort(files); + + StringBuilder text = new StringBuilder(); + + printFooter(text); + + // get all the file details for each mine: for (File file : files) { - + addFileToText(file, text); - } + return text; } @@ -156,11 +276,13 @@ public StringBuilder getSupportSubmitListenersData( String listenerType ) { if ( "blockBreak".equalsIgnoreCase( listenerType ) || "all".equalsIgnoreCase( listenerType ) ) { + sb.append( "||Listeners blockBreak||" ); sb.append( Prison.get().getPlatform().dumpEventListenersBlockBreakEvents() ); } if ( "chat".equalsIgnoreCase( listenerType ) || "all".equalsIgnoreCase( listenerType ) ) { + sb.append( "||Listeners chat||" ); sb.append( Prison.get().getPlatform().dumpEventListenersPlayerChatEvents() ); } @@ -172,12 +294,109 @@ public StringBuilder getSupportSubmitListenersData( String listenerType ) { if ( "playerInteract".equalsIgnoreCase( listenerType ) || "all".equalsIgnoreCase( listenerType ) ) { + sb.append( "||Listeners playerInteract||" ); sb.append( Prison.get().getPlatform().dumpEventListenersPlayerInteractEvents() ); } return sb; } + + public StringBuilder getCommandStatsDetailData() { + StringBuilder sb = new StringBuilder(); + + sb.append( "\n\n" ); + + List cmds = getCommandStats(); + cmds.add( 1, "||CommandStats List||" ); + + for (String cmd : cmds) { + + sb.append( cmd ).append( "\n" ); + } + + return sb; + } + + public void getCommandStatsData() { + + List cmds = getCommandStats(); + for (String cmd : cmds) { + + Output.get().logInfo( cmd ); + } + } + + private List getCommandStats() { + List results = new ArrayList<>(); + + DecimalFormat iFmt = Prison.get().getDecimalFormatInt(); + DecimalFormat dFmt = Prison.get().getDecimalFormatDouble(); + + TreeSet allCmds = Prison.get().getCommandHandler().getAllRegisteredCommands(); + + results.add( "Prison Command Stats:" ); + results.add( + Output.stringFormat( " &a&n%-40s&r &a&n%7s&r &a&n%-11s&r", + " Commands ", " Usage ", " Avg ms ") ); + + int count = 0; + int totals = 0; + double totalDuration = 0d; + for (RegisteredCommand cmd : allCmds) { + + if ( cmd.getUsageCount() > 0 ) { + + double duration = cmd.getUsageRunTimeNanos() / (double) cmd.getUsageCount() / 1000000.0d; + + results.add( Output.stringFormat( " &2%-40s &2%7s &2%11s", + cmd.getCompleteLabel(), + iFmt.format( cmd.getUsageCount() ), + dFmt.format( duration ) + ) ); + count++; + totals += cmd.getUsageCount(); + totalDuration += cmd.getUsageRunTimeNanos(); + } + } + + results.add( Output.stringFormat(" &3Total Registered Prison Commands: &7%9s", iFmt.format( allCmds.size() )) ); + results.add( Output.stringFormat(" &3Total Prison Commands Listed: &7%9s", iFmt.format( count )) ); + results.add( Output.stringFormat(" &3Total Prison Command Usage: &7%9s", iFmt.format( totals )) ); + + double avgDuration = totalDuration / (double) count / 1000000.0d; + results.add( Output.stringFormat(" &3Average Command Duration ms: &7%9s", dFmt.format( avgDuration )) ); + + results.add( " &d&oNOTE: Async Commands like '/mines reset' will not show actual runtime values. " ); + + + return results; + } + + + public StringBuilder getPrisonBackupLogsData() { + StringBuilder sb = new StringBuilder(); + + // Include Prison backup logs: + sb.append( "\n\n" ); + sb.append( "Prison Backup Logs:" ).append( "\n" ); + List backupLogs = getPrisonBackupLogs(); + + for (String log : backupLogs) { + sb.append( Output.decodePercentEncoding(log) ).append( "\n" ); + } + + return sb; + } + + + public List getPrisonBackupLogs() { + PrisonBackups prisonBackup = new PrisonBackups(); + List backupLogs = prisonBackup.backupReport02BackupLog(); + return backupLogs; + } + + public void readFileToStringBulider(File textFile, StringBuilder text) { try (BufferedReader br = Files.newBufferedReader(textFile.toPath());) { String line = br.readLine(); @@ -220,7 +439,8 @@ private List listFiles(String path, String fileSuffix) { } private void addFileToText(File file, StringBuilder sb) { - DecimalFormat dFmt = Prison.get().getDecimalFormatInt(); + DecimalFormat iFmt = Prison.get().getDecimalFormatInt(); + DecimalFormat dFmt = Prison.get().getDecimalFormatDouble(); SimpleDateFormat sdFmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); @@ -271,12 +491,19 @@ else if ( "mines".equalsIgnoreCase(parentDirName) ) { .append( "File" ) .append( "||\n" ); - - sb.append("File Name: ").append(file.getName()).append("\n"); - sb.append("File Path: ").append(file.getAbsolutePath()).append("\n"); - sb.append("File Size: ").append(dFmt.format(file.length())).append(" bytes\n"); - sb.append("File Date: ").append(sdFmt.format(new Date(file.lastModified()))).append(" bytes\n"); - sb.append("File Stats: ").append(file.exists() ? "EXISTS " : "").append(file.canRead() ? "READABLE " : "") + String prisonPath = Prison.get().getDataFolder().getAbsolutePath(); + String filePath = file.getAbsolutePath().replace( prisonPath, "" ); + + long fileSize = file.length(); + double fileSizeKB = fileSize / 1024.0; + + sb.append("File Name: ").append( file.getName() ).append("\n"); + sb.append("Prison Path: ").append( prisonPath ).append("\n"); + sb.append("File Path: ").append( filePath ).append("\n"); + sb.append("File Size: ").append( iFmt.format( fileSize ) ).append(" bytes\n"); + sb.append("File Size: ").append( dFmt.format( fileSizeKB ) ).append(" KB\n"); + sb.append("File Date: ").append( sdFmt.format(new Date(file.lastModified())) ).append(" \n"); + sb.append("File Stats: ").append( file.exists() ? "EXISTS " : "" ).append(file.canRead() ? "READABLE " : "") .append(file.canWrite() ? "WRITEABLE " : "").append("\n"); sb.append("\n"); diff --git a/prison-mines/src/main/java/tech/mcprison/prison/mines/commands/MinesCommands.java b/prison-mines/src/main/java/tech/mcprison/prison/mines/commands/MinesCommands.java index 505fbcae0..f50b595e6 100644 --- a/prison-mines/src/main/java/tech/mcprison/prison/mines/commands/MinesCommands.java +++ b/prison-mines/src/main/java/tech/mcprison/prison/mines/commands/MinesCommands.java @@ -897,6 +897,8 @@ private ChatDisplay mineInfoDetails( CommandSender sender, boolean isMineStats, DecimalFormat fFmt = Prison.get().getDecimalFormat("#,##0.00"); ChatDisplay chatDisplay = new ChatDisplay("&bMine: &3" + m.getName()); + + chatDisplay.addSupportHyperLinkData( "Mine %s", m.getName() ); { RowComponent row = new RowComponent(); diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/LadderCommands.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/LadderCommands.java index f1f42181c..f8d9ab32a 100644 --- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/LadderCommands.java +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/LadderCommands.java @@ -94,11 +94,57 @@ public void ladderRemove(CommandSender sender, @Arg(name = "ladderName") String @Command(identifier = "ranks ladder list", description = "Lists all rank ladders.", onlyPlayers = false, permissions = "ranks.ladder") public void ladderList(CommandSender sender) { - ChatDisplay display = new ChatDisplay("Ladders"); - - display.addSupportHyperLinkData( "Ladder List" ); + ChatDisplay display = getLadderList(); + +// ChatDisplay display = new ChatDisplay("Ladders"); +// +// display.addSupportHyperLinkData( "Ladder List" ); +// +// BulletedListComponent.BulletedListBuilder list = +// new BulletedListComponent.BulletedListBuilder(); +// +//// DecimalFormat dFmt = Prison.get().getDecimalFormat( "#,##0.0000" ); +// +//// String header = String.format( +//// "&d%-12s %16s %5s %12s %12s", +//// "Ladder", +//// "Rank Cost Mult", +//// "Ranks", +//// "First Rank", +//// "Last Rank" +//// ); +// +// list.add( PrisonRanks.getInstance().getLadderManager().printRankLadderInfoHeader() ); +// +// for (RankLadder ladder : PrisonRanks.getInstance().getLadderManager().getLadders()) { +// +//// int rankCount = ladder.getRanks() == null ? 0 : ladder.getRanks().size(); +//// +//// Rank firstRank = rankCount == 0 ? null : ladder.getRanks().get(0); +//// Rank lastRank = rankCount == 0 ? null : ladder.getRanks().get( rankCount - 1 ); +//// +//// String ladderInfo = String.format( +//// "&7%-12s %16s %4d %-12s %-12s", +//// ladder.getName(), +//// dFmt.format( ladder.getRankCostMultiplierPerRank() ), +//// rankCount, +//// firstRank.getName(), +//// lastRank.getName() +//// ); +// +// list.add( PrisonRanks.getInstance().getLadderManager().printRankLadderInfoDetail( ladder ) ); +// } +// +// display.addComponent(list.build()); + display.send(sender); + } + + public ChatDisplay getLadderList() { + ChatDisplay display = new ChatDisplay("Ladders"); + + display.addSupportHyperLinkData( "Ladder List" ); BulletedListComponent.BulletedListBuilder list = new BulletedListComponent.BulletedListBuilder(); @@ -136,8 +182,8 @@ public void ladderList(CommandSender sender) { } display.addComponent(list.build()); - - display.send(sender); + + return display; } // @Command(identifier = "ranks ladder listranks", description = "Lists the ranks within a ladder.", diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/SpigotPlatform.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/SpigotPlatform.java index a1d599490..5920c43a5 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/SpigotPlatform.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/SpigotPlatform.java @@ -98,6 +98,7 @@ import tech.mcprison.prison.output.Output; import tech.mcprison.prison.output.RowComponent; import tech.mcprison.prison.ranks.PrisonRanks; +import tech.mcprison.prison.ranks.commands.LadderCommands; import tech.mcprison.prison.ranks.commands.RanksCommands; import tech.mcprison.prison.ranks.data.PlayerRank; import tech.mcprison.prison.ranks.data.Rank; @@ -2880,12 +2881,17 @@ public String getMinesListString() { ChatDisplay display = new ChatDisplay("Mines"); + + display.addSupportHyperLinkData( "Mines List" ); + + // get the mine list: mc.getMinesList( display, MineManager.MineSortOrder.sortOrder, "all", null ); StringBuilder sb = display.toStringBuilder(); sb.append( "\n" ); + // get the mine details for all mines: mc.allMinesInfoDetails( sb ); return sb.toString(); @@ -2894,20 +2900,31 @@ public String getMinesListString() { @Override public String getRanksListString() { + StringBuilder sb = new StringBuilder(); + + LadderCommands lc = + PrisonRanks.getInstance().getRankManager().getLadderCommands(); RanksCommands rc = PrisonRanks.getInstance().getRankManager().getRanksCommands(); + sb.append( "\n\n" ); + + ChatDisplay displayLadders = lc.getLadderList(); + + sb.append( displayLadders.toStringBuilder() ); + sb.append( "\n" ); - ChatDisplay display = new ChatDisplay("Ranks"); RankPlayer rPlayer = null; - rc.listAllRanksByLadders( display, true, rPlayer ); - StringBuilder sb = display.toStringBuilder(); + ChatDisplay displayRanks = new ChatDisplay("Ranks"); + rc.listAllRanksByLadders( displayRanks, true, rPlayer ); - sb.append( "\n" ); - + sb.append( displayRanks.toStringBuilder() ); + sb.append( "\n" ); + + rc.listAllRanksByInfo( sb ); // rc.allRanksInfoDetails( sb ); From b8d00509f66e95ece76176fc5e6478a0e30bab26 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Thu, 20 Jul 2023 10:38:15 -0400 Subject: [PATCH 040/151] Prison Support: Support HTML file: Added a color test to prison, color matched on the console's colors to provide an accurate reproduction and match with the console. Added the ability to support themes: console is the primary, with Madog being an alternative. Can have others themes too. Fixed a few layout issues. Added the ladder listing, which did not exist before. Setup the placeholders for the hyperlinks... they will be added next along with the auto generation of a table of contents. --- docs/changelog_v3.3.x.md | 7 +- .../tech/mcprison/prison/PrisonCommand.java | 24 ++- .../prison/discord/PrisonSupportFiles.java | 191 +++++++++++++----- .../mcprison/prison/util/PrisonStatsUtil.java | 41 ++++ .../discord/PrisonSupportFilesTest.java | 10 +- 5 files changed, 210 insertions(+), 63 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 4e158ea17..3284f2804 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -14,7 +14,12 @@ These change logs represent the work that has been going on within prison. -# 3.3.0-alpha.15a 2023-07-19 +# 3.3.0-alpha.15a 2023-07-20 + + +* **Prison Support: Support HTML file: Added a color test to prison, color matched on the console's colors to provide an accurate reproduction and match with the console.** +Added the ability to support themes: console is the primary, with Madog being an alternative. Can have others themes too. +Fixed a few layout issues. Added the ladder listing, which did not exist before. Setup the placeholders for the hyperlinks... they will be added next along with the auto generation of a table of contents. * **Prison Support: More enhancements to the html save file.** diff --git a/prison-core/src/main/java/tech/mcprison/prison/PrisonCommand.java b/prison-core/src/main/java/tech/mcprison/prison/PrisonCommand.java index aa1e49c5c..69891a374 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/PrisonCommand.java +++ b/prison-core/src/main/java/tech/mcprison/prison/PrisonCommand.java @@ -1349,7 +1349,7 @@ public void supportSaveToFile(CommandSender sender, StringBuilder text = Prison.get().getPrisonStatsUtil().getSupportSubmitBasic(); - getSupportFile().saveToSupportFile( text ); + getSupportFile().saveToSupportFile( text, getSupportName() ); sender.sendMessage(" - Support 'basic' data was just added to the support output file." ); sender.sendMessage(" - Includes: version, listeners, command stats, ladders, Ranks, Mines, and all Config files." ); @@ -1366,7 +1366,19 @@ public void supportSaveToFile(CommandSender sender, } } - + + @Command(identifier = "prison support colorTest", + description = "Displays a test swatch of minecraft colors .", + onlyPlayers = false, permissions = "prison.debug" ) + public void supportColorTest(CommandSender sender + ) { + + StringBuilder sb = Prison.get().getPrisonStatsUtil().getColorTest(); + + for (String line : sb.toString().split("\n")) { + Output.get().logInfo(line); + } + } @Command(identifier = "prison support submit version", description = "For Prison support: This will copy the contents of '/prison version all' " + @@ -1426,7 +1438,7 @@ public void supportSubmitVersion(CommandSender sender if ( getSupportFile() != null ) { - getSupportFile().saveToSupportFile( text ); + getSupportFile().saveToSupportFile( text, getSupportName() ); sender.sendMessage(" - Support 'version' data was just added to the support output file." ); sender.sendMessage( getSupportFile().getFileStats( text.length() ) ); @@ -1480,7 +1492,7 @@ public void supportSubmitConfigs(CommandSender sender if ( getSupportFile() != null ) { - getSupportFile().saveToSupportFile( text ); + getSupportFile().saveToSupportFile( text, getSupportName() ); sender.sendMessage(" - Support 'configs' data was just added to the support output file." ); sender.sendMessage( getSupportFile().getFileStats( text.length() ) ); @@ -1533,7 +1545,7 @@ public void supportSubmitRanks(CommandSender sender if ( getSupportFile() != null ) { - getSupportFile().saveToSupportFile( text ); + getSupportFile().saveToSupportFile( text, getSupportName() ); sender.sendMessage(" - Support 'ranks' data was just added to the support output file." ); sender.sendMessage( getSupportFile().getFileStats( text.length() ) ); @@ -1583,7 +1595,7 @@ public void supportSubmitMines(CommandSender sender if ( getSupportFile() != null ) { - getSupportFile().saveToSupportFile( text ); + getSupportFile().saveToSupportFile( text, getSupportName() ); sender.sendMessage(" - Support 'mines' data was just added to the support output file." ); sender.sendMessage( getSupportFile().getFileStats( text.length() ) ); diff --git a/prison-core/src/main/java/tech/mcprison/prison/discord/PrisonSupportFiles.java b/prison-core/src/main/java/tech/mcprison/prison/discord/PrisonSupportFiles.java index 7783a469d..940692dfb 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/discord/PrisonSupportFiles.java +++ b/prison-core/src/main/java/tech/mcprison/prison/discord/PrisonSupportFiles.java @@ -15,7 +15,7 @@ public class PrisonSupportFiles { public static final String PSFN_KEY__NAME = "{$name}"; public static final String PSFN_KEY__NUMBER = "{$number}"; public static final String PRISON_SUPPORT_FILE_NAME__PATTERN = "prison_support_" + - PSFN_KEY__NAME + "_" + PSFN_KEY__NUMBER + ".htm"; + PSFN_KEY__NAME + "_" + PSFN_KEY__NUMBER + ".html"; public static final String SECTION_CODE = "§"; @@ -24,46 +24,44 @@ public class PrisonSupportFiles { private boolean colorMapping = true; public enum ColorMaps { - black( "&0", "", "", ".cc0 { color: black; }"), - DarkBlue( "&1", "", "", ".cc1 { color: darkblue; }"), - DarkGreen( "&2", "", "", ".cc2 { color: darkgreen; }"), - DarkCyan( "&3", "", "", ".cc3 { color: darkCyan; }"), - DarkRed( "&4", "", "", ".cc4 { color: darkred; }"), - DarkMagenta( "&5", "", "", ".cc5 { color: darkmagenta; }"), - Orange( "&6", "", "", ".cc6 { color: orange; }"), - LightGray( "&7", "", "", ".cc7 { color: lightgray; }"), - DarkGray( "&8", "", "", ".cc8 { color: darkgray; }"), + black( "&0", "", "" ), + DarkBlue( "&1", "", "" ), + DarkGreen( "&2", "", "" ), + DarkCyan( "&3", "", "" ), + DarkRed( "&4", "", "" ), + DarkMagenta( "&5", "", "" ), + Orange( "&6", "", "" ), + LightGray( "&7", "", "" ), + DarkGray( "&8", "", "" ), - Blue( "&9", "", "", ".cc9 { color: blue; }"), - Green( "&a", "", "", ".cca { color: green; }"), - Cyan( "&b", "", "", ".ccb { color: cyan; }"), - Red( "&c", "", "", ".ccc { color: red[; }"), - Magenta( "&d", "", "", ".ccd { color: magenta; }"), - Yellow( "&e", "", "", ".cce { color: yellow; }"), - White( "&f", "", "", ".ccf { color: white; }"), + Blue( "&9", "", "" ), + Green( "&a", "", "" ), + Cyan( "&b", "", "" ), + Red( "&c", "", "" ), + Magenta( "&d", "", "" ), + Yellow( "&e", "", "" ), + White( "&f", "", "" ), - bold( "&l", "", "", null ), - strike( "&m", "", "", null ), - underline( "&n", "", "", null ), - italic( "&o", "", "", null ), + bold( "&l", "", "" ), + strike( "&m", "", "" ), + underline( "&n", "", "" ), + italic( "&o", "", "" ), - reset( "&r", "", "", null ), + reset( "&r", "", "" ), // Internal codes: - colorMappingOff( "&-", "", "", null ), - colorMappingOn( "&+", "", "", null ) + colorMappingOff( "&-", "", "" ), + colorMappingOn( "&+", "", "" ) ; private final String colorCode; private final String start; private final String end; - private final String css; - private ColorMaps( String colorCode, String start, String end, String css ) { + private ColorMaps( String colorCode, String start, String end ) { this.colorCode = colorCode; this.start = start; this.end = end; - this.css = css; } public String getColorCode() { return colorCode; @@ -74,9 +72,6 @@ public String getStart() { public String getEnd() { return end; } - public String getCss() { - return css; - } public static ColorMaps match( String line ) { ColorMaps results = null; @@ -121,7 +116,7 @@ public File setupSupportFile( String name ) { return getSupportFile(); } - public void saveToSupportFile( StringBuilder text ) { + public void saveToSupportFile( StringBuilder text, String supportName ) { File file = getSupportFile(); @@ -131,7 +126,7 @@ public void saveToSupportFile( StringBuilder text ) { } if ( !file.exists() ) { - saveSupportDataToFile( text ); + saveSupportDataToFile( text, supportName ); } else { appendSaveSupportDataToFile( text ); @@ -151,7 +146,7 @@ public void saveToSupportFile( StringBuilder text ) { // } - private void saveSupportDataToFile( StringBuilder text ) { + private void saveSupportDataToFile( StringBuilder text, String supportName ) { File file = getSupportFile(); try ( @@ -159,10 +154,13 @@ private void saveSupportDataToFile( StringBuilder text ) { ) { - bw.write( getGlobalCss() ); + bw.write( getHtmlHead( supportName ) ); + bw.write( getHtmlBodyStart() ); writeBufferedWriter( bw, text ); +// bw.write( getHtmlBodyEnd() ); + } catch (IOException e) { e.printStackTrace(); @@ -241,18 +239,21 @@ protected String convertColorCodes(String line) { sb.append( line.substring(idx,idx+1)); i = idx; } +// else if ( cm == ColorMaps.colorMappingOn ) { +// +// setColorMapping( true ); +// sb.append( right.replace( cm.getColorCode(), "" ) ); +// break; +// } +// else if ( !isColorMapping() ) { +// i = idx + 1; +// } else if ( cm == ColorMaps.colorMappingOff ) { setColorMapping( false ); sb.append( right.replace( cm.getColorCode(), "" ) ); break; } - else if ( cm == ColorMaps.colorMappingOn ) { - - setColorMapping( true ); - sb.append( right.replace( cm.getColorCode(), "" ) ); - break; - } else if ( cm == ColorMaps.reset ) { sb.append( sbEnd ); sbEnd.setLength(0); @@ -263,10 +264,11 @@ else if ( cm == ColorMaps.reset ) { sbEnd.insert(0, cm.getEnd() ); i = idx + 1; } + } sb.append( sbEnd ) - .append( "
"); + .append( "\n"); } else { ColorMaps cm = ColorMaps.match( line ); @@ -277,11 +279,11 @@ else if ( cm == ColorMaps.reset ) { // Return the line without the color code: sb.append( line.replace( cm.getColorCode(), "" ) ) - .append( "
"); + .append( "\n"); } else { sb.append( line ) - .append( "
"); + .append( "\n"); } } @@ -354,6 +356,44 @@ private File createSupportFile( String name ) { return file; } + private String getHtmlHead( String supportName ) { + StringBuilder sb = new StringBuilder(); + + sb.append( "\n" ) + .append( "\n" ) + .append( "\n" ) + .append( "Prison Support: " ) + .append( supportName ) + .append( "\n" ) + .append( " \n" ) + .append( getGlobalCss() ) + .append( "\n" ); + + return sb.toString(); + } + + private String getHtmlBodyStart() { + StringBuilder sb = new StringBuilder(); + + sb.append( "\n"); + sb.append( "
\n"); + sb.append( " "); + sb.append( "\n"); + sb.append( "
\n"); + + return sb.toString(); + } + + @SuppressWarnings("unused") + private String getHtmlBodyEnd() { + StringBuilder sb = new StringBuilder(); + + sb.append( "\n" ); + sb.append( "\n" ); + + return sb.toString(); + } + private String getGlobalCss() { StringBuilder sb = new StringBuilder(); @@ -361,18 +401,67 @@ private String getGlobalCss() { .append( "body {\n") .append( " font-family: ui-monospaced, monospaced, \"Lucida Console\", \"Courier New\", \"Courier\";\n") - .append( " color: white;\n") - .append( " background-color: #494949;\n") .append( " white-space: pre;\n") .append( "}\n"); + + + sb.append( "body.console { color: white; background-color: #000000; }\n"); + sb.append( "body.console .cc0 { color: black; }\n"); + sb.append( "body.console .cc1 { color: #0037da; }\n"); + sb.append( "body.console .cc2 { color: #13a10e; }\n"); + sb.append( "body.console .cc3 { color: #3a96dd; }\n"); + sb.append( "body.console .cc4 { color: #c50f1f; }\n"); + sb.append( "body.console .cc5 { color: #881798; }\n"); + sb.append( "body.console .cc6 { color: #c19c00; }\n"); + sb.append( "body.console .cc7 { color: #cccccc; }\n"); + sb.append( "body.console .cc8 { color: #767676; }\n"); + sb.append( "body.console .cc9 { color: #3b78ff; }\n"); + sb.append( "body.console .cca { color: #16c60c; }\n"); + sb.append( "body.console .ccb { color: #61d6d6; }\n"); + sb.append( "body.console .ccc { color: #e74856; }\n"); + sb.append( "body.console .ccd { color: #b4009e; }\n"); + sb.append( "body.console .cce { color: #f9f1a5; }\n"); + sb.append( "body.console .ccf { color: #f2f2f2; }\n"); + + + sb.append( "body.madog { color: white; background-color: #171717; }\n"); + sb.append( "body.madog .cc0 { color: black; }\n"); + sb.append( "body.madog .cc1 { color: darkblue; }\n"); + sb.append( "body.madog .cc2 { color: #0F0; }\n"); + sb.append( "body.madog .cc3 { color: #ff8f00; }\n"); + sb.append( "body.madog .cc4 { color: darkred; }\n"); + sb.append( "body.madog .cc5 { color: #F0F; }\n"); + sb.append( "body.madog .cc6 { color: orange; }\n"); + sb.append( "body.madog .cc7 { color: #aaa6a6; }\n"); + sb.append( "body.madog .cc8 { color: darkgray; }\n"); + sb.append( "body.madog .cc9 { color: yellow; }\n"); + sb.append( "body.madog .cca { color: #00c3ff; }\n"); + sb.append( "body.madog .ccb { color: cyan; }\n"); + sb.append( "body.madog .ccc { color: red; }\n"); + sb.append( "body.madog .ccd { color: magenta; }\n"); + sb.append( "body.madog .cce { color: yellow; }\n"); + sb.append( "body.madog .ccf { color: white; }\n"); + + //sb.append( "body.console \n"); + + sb.append( ".buttons { \n"); + sb.append( " position: fixed;\n" ); + sb.append( " top: 0;\n" ); + sb.append( " right: 0;\n" ); + sb.append( " width: 150px;\n" ); + sb.append( " height: 34px;\n" ); + sb.append( "} \n"); + sb.append( ".button { \n"); + sb.append( " display: inline-block; \n"); + sb.append( "} \n"); - for (ColorMaps colorMap : ColorMaps.values()) { - if ( colorMap.getCss() != null ) { - - sb.append( colorMap.getCss() ).append( "\n" ); - } - } +// for (ColorMaps colorMap : ColorMaps.values()) { +// if ( colorMap.getCss() != null ) { +// +// sb.append( colorMap.getCss() ).append( "\n" ); +// } +// } sb.append( "" ); diff --git a/prison-core/src/main/java/tech/mcprison/prison/util/PrisonStatsUtil.java b/prison-core/src/main/java/tech/mcprison/prison/util/PrisonStatsUtil.java index d7f0f2599..30f6121db 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/util/PrisonStatsUtil.java +++ b/prison-core/src/main/java/tech/mcprison/prison/util/PrisonStatsUtil.java @@ -102,6 +102,9 @@ public StringBuilder getSupportSubmitBasic() { // Config files: sb.append( getSupportSubmitConfigsData() ); + + sb.append( getColorTest() ); + return sb; } @@ -138,6 +141,44 @@ public StringBuilder getSupportSubmitVersionData() { return text; } + + public StringBuilder getColorTest() { + StringBuilder sb = new StringBuilder(); + + sb.append( "\n\n" ); + sb.append( "Color Test:\n\n" ); + sb.append( "||Color Test||\n" ); + + sb.append( "&0######### &r&1######### &r&2#########\n" ); + sb.append( "&0### 0 ### &r&1### 1 ### &r&2### 2 ###\n" ); + sb.append( "&0######### &r&1######### &r&2#########\n" ); + + sb.append( "&3######### &r&4######### &r&5#########\n" ); + sb.append( "&3### 3 ### &r&4### 4 ### &r&5### 5 ###\n" ); + sb.append( "&3######### &r&4######### &r&5#########\n" ); + + sb.append( "&6######### &r&7######### &r&8#########\n" ); + sb.append( "&6### 6 ### &r&7### 7 ### &r&8### 8 ###\n" ); + sb.append( "&6######### &r&7######### &r&8#########\n" ); + + sb.append( "&9######### &r&a######### &r&b#########\n" ); + sb.append( "&9### 9 ### &r&a### a ### &r&b### b ###\n" ); + sb.append( "&9######### &r&a######### &r&b#########\n" ); + + sb.append( "&c######### &r&d######### &r&e#########\n" ); + sb.append( "&c### c ### &r&d### d ### &r&e### e ###\n" ); + sb.append( "&c######### &r&d######### &r&e#########\n" ); + + sb.append( "&f######### &r\n" ); + sb.append( "&f### f ### &r\n" ); + sb.append( "&f######### &r\n" ); + + sb.append( "\n\n" ); + + return sb; + } + + public StringBuilder getSupportSubmitConfigsData() { Prison.get().getPlatform().saveResource("plugin.yml", true); diff --git a/prison-core/src/test/java/tech/mcprison/prison/discord/PrisonSupportFilesTest.java b/prison-core/src/test/java/tech/mcprison/prison/discord/PrisonSupportFilesTest.java index e058f19e1..69d495bdd 100644 --- a/prison-core/src/test/java/tech/mcprison/prison/discord/PrisonSupportFilesTest.java +++ b/prison-core/src/test/java/tech/mcprison/prison/discord/PrisonSupportFilesTest.java @@ -12,27 +12,27 @@ public class PrisonSupportFilesTest public void test() { String t1 = "This is a test"; - String r1 = "This is a test
"; + String r1 = "This is a test\n"; assertEquals(r1, convertColorCodes(t1) ); String t2 = "&3This is a test"; - String r2 = "This is a test
"; + String r2 = "This is a test\n"; assertEquals(r2, convertColorCodes(t2) ); String t3 = "&3This is a &1test"; String r3 = "This is a " - + "test
"; + + "test\n"; assertEquals(r3, convertColorCodes(t3) ); String t4 = "&3This is a &1test & sample"; String r4 = "This is a " - + "test & sample
"; + + "test & sample\n"; assertEquals(r4, convertColorCodes(t4) ); @@ -40,7 +40,7 @@ public void test() { String t5 = "&3This is a &1test & a&r fun &1sample"; String r5 = "This is a " + "test & a" - + " fun sample
"; + + " fun sample\n"; assertEquals(r5, convertColorCodes(t5) ); From 0f0ca7afd7081647d91f914efae7e9211ab2ccc0 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Thu, 20 Jul 2023 10:40:39 -0400 Subject: [PATCH 041/151] Fixed a color code conflict in the ranks list when displaying the default rank. It wasn't wrong, but it was showing incorrectly. Added a reset `&r` and that fixed it. Almost like too much nesting got in the way. --- docs/changelog_v3.3.x.md | 4 ++++ .../tech/mcprison/prison/ranks/commands/RanksCommands.java | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 3284f2804..08ffdae39 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -17,6 +17,10 @@ These change logs represent the work that has been going on within prison. # 3.3.0-alpha.15a 2023-07-20 +* **Fixed a color code conflict in the ranks list when displaying the default rank.** +It wasn't wrong, but it was showing incorrectly. Added a reset `&r` and that fixed it. Almost like too much nesting got in the way. + + * **Prison Support: Support HTML file: Added a color test to prison, color matched on the console's colors to provide an accurate reproduction and match with the console.** Added the ability to support themes: console is the primary, with Madog being an alternative. Can have others themes too. Fixed a few layout issues. Added the ladder listing, which did not exist before. Setup the placeholders for the hyperlinks... they will be added next along with the auto generation of a table of contents. diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/RanksCommands.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/RanksCommands.java index 651155a9e..d1fae5859 100644 --- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/RanksCommands.java +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/RanksCommands.java @@ -976,7 +976,7 @@ private ChatDisplay listRanksOnLadder( RankLadder ladder, boolean hasPerm, RankP if ( defaultRank ) { // Swap out the default placeholder for the actual content: - text = text.replace( "{def}", "&c(&9Default&c)" ); + text = text.replace( "{def}", "&c(&r&9Default&r&c)" ); } String rankName = rank.getName(); From 05e86694d99343371e720da16ae634cede5ff0da Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Fri, 21 Jul 2023 03:12:28 -0400 Subject: [PATCH 042/151] Enable all Ranks to be used with the sellall rank multiplier. It used to be limited to just prestige ranks, but there has been requests to expand to all ranks. --- docs/changelog_v3.3.x.md | 4 ++ .../commands/PrisonSpigotSellAllCommands.java | 49 ++++++++++----- .../prison/spigot/sellall/SellAllUtil.java | 59 +++++++++++-------- 3 files changed, 72 insertions(+), 40 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 08ffdae39..433ccc261 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -17,6 +17,10 @@ These change logs represent the work that has been going on within prison. # 3.3.0-alpha.15a 2023-07-20 +* **Enable all Ranks to be used with the sellall rank multiplier.** +It used to be limited to just prestige ranks, but there has been requests to expand to all ranks. + + * **Fixed a color code conflict in the ranks list when displaying the default rank.** It wasn't wrong, but it was showing incorrectly. Added a reset `&r` and that fixed it. Almost like too much nesting got in the way. diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/commands/PrisonSpigotSellAllCommands.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/commands/PrisonSpigotSellAllCommands.java index c8a3b9b66..292d23814 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/commands/PrisonSpigotSellAllCommands.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/commands/PrisonSpigotSellAllCommands.java @@ -808,7 +808,8 @@ private void sellAllEditCommand(CommandSender sender, } } - @Command(identifier = "sellall multiplier list", description = "SellAll multiplier command list", + @Command(identifier = "sellall multiplier list", + description = "Lists all of the SellAll Rank multipliers", permissions = "prison.admin", onlyPlayers = false) private void sellAllMultiplierCommand(CommandSender sender){ @@ -848,7 +849,7 @@ private void sellAllMultiplierCommand(CommandSender sender){ } - ChatDisplay chatDisplay = new ChatDisplay("&bSellall Prestige Multipliers list: &3(&b" + keys.size() + "&3)" ); + ChatDisplay chatDisplay = new ChatDisplay("&bSellall Rank Multipliers list: &3(&b" + keys.size() + "&3)" ); int lines = 0; int columns = 0; @@ -890,13 +891,30 @@ private void sellAllMultiplierCommand(CommandSender sender){ } - @Command(identifier = "sellall multiplier add", description = "SellAll add a multiplier. Permission multipliers for player's prison.sellall.multiplier., example prison.sellall.multiplier.2 will add a 2x multiplier," + - "There's also another kind of Multiplier called permission multipliers, they're permissions that you can give to players to give them a multiplier, remember that their format is prison.sellall.multiplier.2 (for example), and this example will give you a " + - "total of 3x multiplier (1x default + 2x permission = 3x).", + @Command(identifier = "sellall multiplier add", + description = "Add a sellall multiplier based upon the player's rank. " + + "All ranks that a player has, could have their own multiplier, that can " + + "be combined to help the player increase the value of what they are selling. " + + "These multipliers will be combined with all other player mulitpliers to " + + "adjust the sales price within sellall. Multipliers can be from these " + + "rank multipliers, and also from permission multipliers. " + + "All players start off with a default value of a multiplier with a value of 1, which " + + "equates to 100% of what they sell: no loss and no gain. From there, multipliers that " + + "you give to players can be integers, or doubles. They can be greater than 1, or less than " + + "1, or even negative. All multipliers are added together to provide the player's total " + + "amount. " + + "Permission multipliers for player's `prison.sellall.multiplier.`, " + + "example `prison.sellall.multiplier.2` will add a 2x multiplier. " + + "The multiplier values do not have to integers, but can be less than one, or " + + "doubles. " + + "There's also another kind of Multiplier called permission multipliers, they're permissions " + + "that you can give to players to give them a multiplier, remember that their format is " + + "'prison.sellall.multiplier.2.5' (for example), and this example will give you a " + + "total of 3.5x multiplier (1x default + 2.5x permission = 3.5x).", permissions = "prison.admin", onlyPlayers = false) private void sellAllAddMultiplierCommand(CommandSender sender, - @Arg(name = "Prestige", description = "Prestige to hook to the multiplier.") String prestige, - @Arg(name = "multiplier", description = "Multiplier value.") Double multiplier){ + @Arg(name = "rank", description = "The rank name for the multiplier.") String rank, + @Arg(name = "multiplier", description = "Multiplier value.") Double multiplier) { if (!isEnabled()) return; @@ -910,18 +928,19 @@ private void sellAllAddMultiplierCommand(CommandSender sender, return; } - if (sellAllUtil.addPrestigeMultiplier(prestige, multiplier)){ + if (sellAllUtil.addSellallRankMultiplier(rank, multiplier)){ Output.get().sendInfo(sender, messages.getString(MessagesConfig.StringID.spigot_message_sellall_multiplier_add_success)); } else { - Output.get().sendInfo( sender, "Failed to add sellall prestige multiplier." ); + Output.get().sendInfo( sender, "Failed to add sellall rank multiplier." ); } } - @Command(identifier = "sellall multiplier delete", description = "SellAll delete a multiplier.", + @Command(identifier = "sellall multiplier delete", + description = "Remove a SellAll rank multiplier.", permissions = "prison.admin", onlyPlayers = false) private void sellAllDeleteMultiplierCommand(CommandSender sender, - @Arg(name = "Prestige", description = "Prestige hooked to the multiplier.") String prestige){ + @Arg(name = "Rank", description = "The rank name of the multiplier.") String rank){ if (!isEnabled()) return; @@ -935,17 +954,17 @@ private void sellAllDeleteMultiplierCommand(CommandSender sender, return; } - if (prestige == null){ + if (rank == null){ Output.get().sendWarn(sender, messages.getString(MessagesConfig.StringID.spigot_message_command_wrong_format)); return; } - if (sellAllUtil.sellAllConfig.getConfigurationSection("Multiplier." + prestige) == null){ - Output.get().sendWarn(sender, messages.getString(MessagesConfig.StringID.spigot_message_sellall_multiplier_cant_find) + " [" + prestige + "]"); + if (sellAllUtil.sellAllConfig.getConfigurationSection("Multiplier." + rank) == null){ + Output.get().sendWarn(sender, messages.getString(MessagesConfig.StringID.spigot_message_sellall_multiplier_cant_find) + " [" + rank + "]"); return; } - if (sellAllUtil.removePrestigeMultiplier(prestige)){ + if (sellAllUtil.removeSellallRankMultiplier(rank)){ Output.get().sendInfo(sender, messages.getString(MessagesConfig.StringID.spigot_message_sellall_multiplier_delete_success)); } } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/sellall/SellAllUtil.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/sellall/SellAllUtil.java index 92c957eab..e3108d1a4 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/sellall/SellAllUtil.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/sellall/SellAllUtil.java @@ -1150,8 +1150,10 @@ public HashMap initPrestigeMultipliers(){ return prestigeMultipliers; } + // NOTE: They key is the same as the rank name... so no need to read the PRESTIGE_NAME or RANK_NAME: for (String key : sellAllConfig.getConfigurationSection("Multiplier").getKeys(false)){ - prestigeMultipliers.put(sellAllConfig.getString("Multiplier." + key + ".PRESTIGE_NAME"), sellAllConfig.getDouble("Multiplier." + key + ".MULTIPLIER")); + prestigeMultipliers.put( key, + sellAllConfig.getDouble("Multiplier." + key + ".MULTIPLIER")); } return prestigeMultipliers; } @@ -1264,16 +1266,16 @@ public boolean addSellAllBlock(XMaterial xMaterial, double value){ // } /** - * Add Multiplier to SellAll depending on the Prestige Rank (Rank from the prestiges ladder). + * Add Multiplier to SellAll depending on the Rank (Rank from any ladder). * - * Return true if edited with success, false if error or Prestige not found. + * Return true if edited with success, false if error or the rank is not found. * - * @param prestigeName - Name of the Prestige as String. + * @param rankName - Name of the Rank as String. * @param multiplier - Double value. * * @return boolean. * */ - public boolean addPrestigeMultiplier(String prestigeName, double multiplier){ + public boolean addSellallRankMultiplier(String rankName, double multiplier){ PrisonRanks rankPlugin = (PrisonRanks) (Prison.get().getModuleManager() == null ? null : Prison.get().getModuleManager().getModule(PrisonRanks.MODULE_NAME) ); @@ -1281,22 +1283,23 @@ public boolean addPrestigeMultiplier(String prestigeName, double multiplier){ return false; } - boolean isPrestigeLadder = rankPlugin.getLadderManager().getLadder("prestiges") != null; - if (!isPrestigeLadder) { - return false; - } + +// boolean isPrestigeLadder = rankPlugin.getLadderManager().getLadder("prestiges") != null; +// if (!isPrestigeLadder) { +// return false; +// } - Rank pRank = rankPlugin.getRankManager().getRank(prestigeName); + Rank rank = rankPlugin.getRankManager().getRank(rankName); - if ( pRank == null ) { + if ( rank == null ) { // Invalid rank! return false; } - if ( !pRank.getLadder().isPrestiges() ) { - // Rank is not in the prestiges ladder: - return false; - } +// if ( !pRank.getLadder().isPrestiges() ) { +// // Rank is not in the prestiges ladder: +// return false; +// } // boolean isInPrestigeLadder = rankPlugin.getLadderManager().getLadder("prestiges").containsRank(rankPlugin.getRankManager().getRank(prestigeName)); // if (!isInPrestigeLadder) { @@ -1307,8 +1310,14 @@ public boolean addPrestigeMultiplier(String prestigeName, double multiplier){ File sellAllFile = new File(SpigotPrison.getInstance().getDataFolder() + "/SellAllConfig.yml"); FileConfiguration conf = YamlConfiguration.loadConfiguration(sellAllFile); - conf.set("Multiplier." + pRank.getName() + ".PRESTIGE_NAME", pRank.getName()); - conf.set("Multiplier." + pRank.getName() + ".MULTIPLIER", multiplier); + if ( rank.getLadder().isPrestiges() ) { + conf.set("Multiplier." + rank.getName() + ".PRESTIGE_NAME", rank.getName()); + } + else { + conf.set("Multiplier." + rank.getName() + ".RANK_NAME", rank.getName()); + } + + conf.set("Multiplier." + rank.getName() + ".MULTIPLIER", multiplier); conf.save(sellAllFile); } @@ -1317,7 +1326,7 @@ public boolean addPrestigeMultiplier(String prestigeName, double multiplier){ return false; } - sellAllPrestigeMultipliers.put( pRank.getName(), multiplier); + sellAllPrestigeMultipliers.put( rank.getName(), multiplier); updateConfig(); return true; @@ -1599,7 +1608,7 @@ public boolean editPrestigeMultiplier(String prestigeName, double multiplier) { return false; } - return addPrestigeMultiplier(prestigeName, multiplier); + return addSellallRankMultiplier(prestigeName, multiplier); } /** @@ -1656,29 +1665,29 @@ public boolean removeSellAllBlock(XMaterial xMaterial){ // } /** - * Remove a Prestige Multiplier by name. + * Remove a Rank Multiplier by name. * * Return true if success, false if error or not found. * - * @param prestigeName - String. + * @param rankName - String. * * @return boolean. * */ - public boolean removePrestigeMultiplier(String prestigeName){ + public boolean removeSellallRankMultiplier(String rankName){ - if (!sellAllPrestigeMultipliers.containsKey(prestigeName)){ + if (!sellAllPrestigeMultipliers.containsKey(rankName)){ return false; } try { File sellAllFile = new File(SpigotPrison.getInstance().getDataFolder() + "/SellAllConfig.yml"); FileConfiguration conf = YamlConfiguration.loadConfiguration(sellAllFile); - conf.set("Multiplier." + prestigeName, null); + conf.set("Multiplier." + rankName, null); conf.save(sellAllFile); } catch (IOException e) { return false; } - sellAllPrestigeMultipliers.remove(prestigeName); + sellAllPrestigeMultipliers.remove(rankName); updateConfig(); return true; } From 3465cd879f4a8d782a3a36f6a7a7ae8c16e033bc Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sun, 23 Jul 2023 22:08:06 -0400 Subject: [PATCH 043/151] Mines set tracer: Update the command to add options for 'clear' the whole mine, and 'corners' where it clears the whole mine but puts the tracer only in the corners. The default option of 'outline' is the default value, and if 'clear' or 'corners' is not set, then it will default to the standard outline, or tracer. --- docs/changelog_v3.3.x.md | 6 +++- .../prison/internal/block/MineResetType.java | 20 ++++++++++++- .../internal/block/MineTargetPrisonBlock.java | 30 +++++++++++++++++-- .../tech/mcprison/prison/util/Location.java | 8 +++++ .../prison/mines/commands/MinesCommands.java | 27 +++++++++++++---- .../mcprison/prison/mines/data/MineReset.java | 21 ++++++++----- .../mines/features/MineLinerBuilder.java | 3 +- .../prison/mines/features/MineMover.java | 3 +- .../mines/features/MineTracerBuilder.java | 4 +-- 9 files changed, 101 insertions(+), 21 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 433ccc261..acad3aa34 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -14,7 +14,11 @@ These change logs represent the work that has been going on within prison. -# 3.3.0-alpha.15a 2023-07-20 +# 3.3.0-alpha.15a 2023-07-23 + + +* **Mines set tracer: Update the command to add options for 'clear' the whole mine, and 'corners' where it clears the whole mine but puts the tracer only in the corners.** +The default option of 'outline' is the default value, and if 'clear' or 'corners' is not set, then it will default to the standard outline, or tracer. * **Enable all Ranks to be used with the sellall rank multiplier.** diff --git a/prison-core/src/main/java/tech/mcprison/prison/internal/block/MineResetType.java b/prison-core/src/main/java/tech/mcprison/prison/internal/block/MineResetType.java index bb38a8643..d4218f223 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/internal/block/MineResetType.java +++ b/prison-core/src/main/java/tech/mcprison/prison/internal/block/MineResetType.java @@ -5,5 +5,23 @@ public enum MineResetType normal, // paged, clear, - tracer; + tracer, + corners, + outline; + + public static MineResetType fromString( String resetType ) { + MineResetType results = normal; + + if ( resetType != null ) { + + for (MineResetType mrt : values() ) { + if ( mrt.name().equalsIgnoreCase( resetType ) ) { + results = mrt; + break; + } + } + } + + return results; + } } diff --git a/prison-core/src/main/java/tech/mcprison/prison/internal/block/MineTargetPrisonBlock.java b/prison-core/src/main/java/tech/mcprison/prison/internal/block/MineTargetPrisonBlock.java index 91cc4dd59..7af56bcf7 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/internal/block/MineTargetPrisonBlock.java +++ b/prison-core/src/main/java/tech/mcprison/prison/internal/block/MineTargetPrisonBlock.java @@ -12,6 +12,7 @@ public class MineTargetPrisonBlock private boolean airBroke; private boolean isEdge; + private boolean isCorner; private boolean exploded; private boolean mined = false; @@ -26,7 +27,9 @@ public class MineTargetPrisonBlock public MineTargetPrisonBlock( PrisonBlockStatusData prisonBlock, World world, - int x, int y, int z, boolean isEdge ) { + int x, int y, int z, + boolean isEdge, + boolean isCorner ) { this.blockKey = new MineTargetBlockKey( world, x, y, z ); this.prisonBlock = prisonBlock; @@ -36,6 +39,7 @@ public MineTargetPrisonBlock( } this.isEdge = isEdge; + this.isCorner = isCorner; } @Override @@ -48,13 +52,26 @@ public PrisonBlock getPrisonBlock( MineResetType resetType ) { final PrisonBlock pBlock; - if ( resetType == MineResetType.tracer && isEdge() ) + if ( ( resetType == MineResetType.tracer || + resetType == MineResetType.outline ) && isEdge() ) { + // Generates the tracer along all edges of the mine + // NOTE: outline and tracer are the same. Outline should be + // converted to tracer, but if it's not, then handle it here + pBlock = PrisonBlock.PINK_STAINED_GLASS; + } + else if ( resetType == MineResetType.corners && isCorner() ) + { + // Generates the trace along all the corners of the mine pBlock = PrisonBlock.PINK_STAINED_GLASS; } else if ( resetType == MineResetType.clear || - resetType == MineResetType.tracer ) + resetType == MineResetType.tracer || + resetType == MineResetType.outline || + resetType == MineResetType.corners ) { + // clears the mine with all AIR, or for tracers the non edges, + // or clears all of the mine except the corners. pBlock = PrisonBlock.AIR; } else if ( getPrisonBlock() != null && @@ -125,6 +142,13 @@ public void setEdge( boolean isEdge ) { this.isEdge = isEdge; } + public boolean isCorner() { + return isCorner; + } + public void setCorner(boolean isCorner) { + this.isCorner = isCorner; + } + public boolean isExploded() { return exploded; } diff --git a/prison-core/src/main/java/tech/mcprison/prison/util/Location.java b/prison-core/src/main/java/tech/mcprison/prison/util/Location.java index 2c2a83a20..734a63a81 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/util/Location.java +++ b/prison-core/src/main/java/tech/mcprison/prison/util/Location.java @@ -38,6 +38,7 @@ public class Location { private Vector direction; private boolean isEdge; + private boolean isCorner; public Location(World world, double x, double y, double z, float pitch, float yaw, Vector direction) { this.world = world; @@ -163,6 +164,13 @@ public void setEdge( boolean isEdge ) { this.isEdge = isEdge; } + public boolean isCorner() { + return isCorner; + } + public void setCorner(boolean isCorner) { + this.isCorner = isCorner; + } + @Override public boolean equals(Object o) { if (this == o) { return true; diff --git a/prison-mines/src/main/java/tech/mcprison/prison/mines/commands/MinesCommands.java b/prison-mines/src/main/java/tech/mcprison/prison/mines/commands/MinesCommands.java index f50b595e6..5ab0f576a 100644 --- a/prison-mines/src/main/java/tech/mcprison/prison/mines/commands/MinesCommands.java +++ b/prison-mines/src/main/java/tech/mcprison/prison/mines/commands/MinesCommands.java @@ -37,6 +37,7 @@ import tech.mcprison.prison.internal.CommandSender; import tech.mcprison.prison.internal.Player; import tech.mcprison.prison.internal.block.Block; +import tech.mcprison.prison.internal.block.MineResetType; import tech.mcprison.prison.internal.block.PrisonBlock; import tech.mcprison.prison.mines.PrisonMines; import tech.mcprison.prison.mines.data.Mine; @@ -2777,25 +2778,41 @@ public void backupMineCommand(CommandSender sender, } - @Command(identifier = "mines set tracer", permissions = "mines.set", - description = "Clear the mine and set a tracer around the outside") + @Command(identifier = "mines set tracer", + description = "Clears the mine of all blocks and sest a tracer of " + + "pink glass blocks around the outside", + permissions = "mines.set") public void setTracerCommand(CommandSender sender, - @Arg(name = "mineName", description = "The name of the mine to set the tracer in.") String mineName) { + @Arg(name = "mineName", + description = "The name of the mine to set the tracer in.") String mineName, + @Arg(name = "options", def = "outline", + description = "Options to control how the tracer is set. " + + "Defaults to 'outline' which draws a pink glass block around the edges of the mine. " + + "The option 'corners' will only place blocks within the corners of the mine. " + + "The option of 'clear' will just clear the mine and will not place any tracers. " + + "[outline corners clear]") String option ) { if (!performCheckMineExists(sender, mineName)) { return; } + MineResetType resetType = MineResetType.fromString(option); + + if ( resetType != MineResetType.corners && resetType != MineResetType.clear ) { + resetType = MineResetType.tracer; + } + + PrisonMines pMines = PrisonMines.getInstance(); Mine mine = pMines.getMine(mineName); - + if ( mine.isVirtual() ) { sender.sendMessage( "&cMine is a virtual mine&7. Use &a/mines set area &7to enable the mine." ); return; } - mine.enableTracer(); + mine.enableTracer( resetType ); } diff --git a/prison-mines/src/main/java/tech/mcprison/prison/mines/data/MineReset.java b/prison-mines/src/main/java/tech/mcprison/prison/mines/data/MineReset.java index 214b745f6..d397bfdc6 100644 --- a/prison-mines/src/main/java/tech/mcprison/prison/mines/data/MineReset.java +++ b/prison-mines/src/main/java/tech/mcprison/prison/mines/data/MineReset.java @@ -596,8 +596,11 @@ public void generateBlockListAsync() { boolean isEdge = xEdge && yEdge || xEdge && zEdge || yEdge && zEdge; + boolean isCorner = xEdge && yEdge && zEdge; + Location targetBlock = new Location(world, x, y, z); targetBlock.setEdge( isEdge ); + targetBlock.setCorner( isCorner ); // MineTargetBlock mtb = null; @@ -1269,8 +1272,11 @@ public List refreshAirCountSyncTaskBuildLocations() { boolean isEdge = xEdge && yEdge || xEdge && zEdge || yEdge && zEdge; + boolean isCorner = xEdge && yEdge && zEdge; + Location targetBlock = new Location(world, x, y, z); targetBlock.setEdge( isEdge ); + targetBlock.setCorner( isCorner ); locations.add( targetBlock ); @@ -1790,11 +1796,12 @@ private void constraintsApplyMin( PrisonBlockStatusData block ) /** * This clears the mine, then provides particle tracers around the outer corners. + * @param resetType */ - public void enableTracer() { + public void enableTracer(MineResetType resetType) { // First clear the mine: - clearMine( true ); + clearMine( resetType ); // Prison.get().getPlatform().enableMineTracer( // getWorldName(), @@ -1817,7 +1824,7 @@ public void enableTracer() { public void adjustSize( Edges edge, int amount ) { // First clear the mine: - clearMine( false ); + clearMine( MineResetType.clear ); // if amount is zero, then just refresh the liner: @@ -1852,7 +1859,7 @@ else if ( amount > 0 ) { } // Finally trace the mine: - clearMine( true ); + clearMine( MineResetType.tracer ); } @@ -1863,10 +1870,10 @@ public void moveMine( Edges edge, int amount ) { } - public void clearMine( boolean tracer ) { + public void clearMine( MineResetType resetType ) { MineTracerBuilder tracerBuilder = new MineTracerBuilder(); - tracerBuilder.clearMine( (Mine) this, tracer ); + tracerBuilder.clearMine( (Mine) this, resetType ); } @@ -1885,7 +1892,7 @@ private void addMineTargetPrisonBlock( PrisonBlockStatusData block, Location tar MineTargetPrisonBlock mtpb = new MineTargetPrisonBlock( block, getWorld().get(), targetBlock.getBlockX(), targetBlock.getBlockY(), targetBlock.getBlockZ(), - targetBlock.isEdge() ); + targetBlock.isEdge(), targetBlock.isCorner() ); synchronized ( getMineStateMutex() ) { diff --git a/prison-mines/src/main/java/tech/mcprison/prison/mines/features/MineLinerBuilder.java b/prison-mines/src/main/java/tech/mcprison/prison/mines/features/MineLinerBuilder.java index 7d61ecec1..250e24613 100644 --- a/prison-mines/src/main/java/tech/mcprison/prison/mines/features/MineLinerBuilder.java +++ b/prison-mines/src/main/java/tech/mcprison/prison/mines/features/MineLinerBuilder.java @@ -8,6 +8,7 @@ import tech.mcprison.prison.internal.World; import tech.mcprison.prison.internal.block.Block; import tech.mcprison.prison.internal.block.BlockFace; +import tech.mcprison.prison.internal.block.MineResetType; import tech.mcprison.prison.internal.block.PrisonBlock; import tech.mcprison.prison.mines.data.Mine; import tech.mcprison.prison.mines.features.MineLinerData.LadderType; @@ -192,7 +193,7 @@ public MineLinerBuilder( Mine mine, Edges edge, LinerPatterns pattern, boolean i this.isForced = isForced; if ( pattern != null ) { - mine.enableTracer(); + mine.enableTracer( MineResetType.clear ); generatePattern( edge ); } diff --git a/prison-mines/src/main/java/tech/mcprison/prison/mines/features/MineMover.java b/prison-mines/src/main/java/tech/mcprison/prison/mines/features/MineMover.java index d5dcee4b5..5d21a7fe6 100644 --- a/prison-mines/src/main/java/tech/mcprison/prison/mines/features/MineMover.java +++ b/prison-mines/src/main/java/tech/mcprison/prison/mines/features/MineMover.java @@ -1,5 +1,6 @@ package tech.mcprison.prison.mines.features; +import tech.mcprison.prison.internal.block.MineResetType; import tech.mcprison.prison.mines.data.Mine; import tech.mcprison.prison.mines.features.MineLinerBuilder.LinerPatterns; import tech.mcprison.prison.util.Bounds; @@ -14,7 +15,7 @@ public MineMover() { public void moveMine( Mine mine, Edges edge, int amount ) { - mine.clearMine( false ); + mine.clearMine( MineResetType.clear ); new MineLinerBuilder( mine, Edges.top, LinerPatterns.repair, false ); new MineLinerBuilder( mine, Edges.bottom, LinerPatterns.repair, false ); diff --git a/prison-mines/src/main/java/tech/mcprison/prison/mines/features/MineTracerBuilder.java b/prison-mines/src/main/java/tech/mcprison/prison/mines/features/MineTracerBuilder.java index 84737cb1b..6f2059a17 100644 --- a/prison-mines/src/main/java/tech/mcprison/prison/mines/features/MineTracerBuilder.java +++ b/prison-mines/src/main/java/tech/mcprison/prison/mines/features/MineTracerBuilder.java @@ -45,7 +45,7 @@ public static TracerType fromString( String type ) { } } - public void clearMine( Mine mine, boolean tracer ) { + public void clearMine( Mine mine, MineResetType resetType ) { if ( mine == null ) { Output.get().logError(" #### Null MINE? ###"); @@ -56,7 +56,7 @@ public void clearMine( Mine mine, boolean tracer ) { return; } - MineResetType resetType = tracer ? MineResetType.tracer : MineResetType.clear; +// MineResetType resetType = tracer ? MineResetType.tracer : MineResetType.clear; MinePagedResetAsyncTask resetTask = new MinePagedResetAsyncTask( mine, resetType ); resetTask.submitTaskAsync(); From 2a99bb9fee07da18c4c93f1a00799f2d51c759d6 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Mon, 24 Jul 2023 22:49:10 -0400 Subject: [PATCH 044/151] Prison support: Added more color related test. Changed the color schema name from 'madog' to 'prison'. --- docs/changelog_v3.3.x.md | 5 ++++- .../prison/discord/PrisonSupportFiles.java | 2 +- .../mcprison/prison/util/PrisonStatsUtil.java | 17 +++++++++++++++++ 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index acad3aa34..45c9836c5 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -14,7 +14,10 @@ These change logs represent the work that has been going on within prison. -# 3.3.0-alpha.15a 2023-07-23 +# 3.3.0-alpha.15a 2023-07-24 + + +* **Prison support: Added more color related test. Changed the color schema name from 'madog' to 'prison'.** * **Mines set tracer: Update the command to add options for 'clear' the whole mine, and 'corners' where it clears the whole mine but puts the tracer only in the corners.** diff --git a/prison-core/src/main/java/tech/mcprison/prison/discord/PrisonSupportFiles.java b/prison-core/src/main/java/tech/mcprison/prison/discord/PrisonSupportFiles.java index 940692dfb..e3bbc920b 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/discord/PrisonSupportFiles.java +++ b/prison-core/src/main/java/tech/mcprison/prison/discord/PrisonSupportFiles.java @@ -378,7 +378,7 @@ private String getHtmlBodyStart() { sb.append( "\n"); sb.append( "
\n"); sb.append( " "); - sb.append( "\n"); + sb.append( "\n"); sb.append( "
\n"); return sb.toString(); diff --git a/prison-core/src/main/java/tech/mcprison/prison/util/PrisonStatsUtil.java b/prison-core/src/main/java/tech/mcprison/prison/util/PrisonStatsUtil.java index 30f6121db..a597c11ae 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/util/PrisonStatsUtil.java +++ b/prison-core/src/main/java/tech/mcprison/prison/util/PrisonStatsUtil.java @@ -173,6 +173,23 @@ public StringBuilder getColorTest() { sb.append( "&f### f ### &r\n" ); sb.append( "&f######### &r\n" ); + + sb.append( "&3&l#####################&r\n" ); + sb.append( "&3&l### Bold & 3 ###&r\n" ); + sb.append( "&3&l#####################&r\n" ); + + sb.append( "&3&m#####################&r\n" ); + sb.append( "&3&m### Strike & 3 ###&r\n" ); + sb.append( "&3&m#####################&r\n" ); + + sb.append( "&3&n#####################&r\n" ); + sb.append( "&3&n### Underline & 3 ###&r\n" ); + sb.append( "&3&n#####################&r\n" ); + + sb.append( "&3&o#####################&r\n" ); + sb.append( "&3&o### Italic & 3 ###&r\n" ); + sb.append( "&3&o#####################&r\n" ); + sb.append( "\n\n" ); return sb; From b1d501e421e25785b5d3b3e45b87820262e96415 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Mon, 24 Jul 2023 22:49:55 -0400 Subject: [PATCH 045/151] Updated a number of prison docs. --- ...son_docs_010_setting_up_a_spigot_server.md | 11 +-- ...rison_docs_012_setting_up_prison_basics.md | 30 +++++--- docs/prison_docs_013_Prison_Help.md | 75 +++++++++++++++++++ docs/prison_docs_101_setting_up_mines.md | 13 +++- docs/prison_docs_111_mine_commands.md | 2 +- 5 files changed, 113 insertions(+), 18 deletions(-) diff --git a/docs/prison_docs_010_setting_up_a_spigot_server.md b/docs/prison_docs_010_setting_up_a_spigot_server.md index 44751af85..700636b22 100644 --- a/docs/prison_docs_010_setting_up_a_spigot_server.md +++ b/docs/prison_docs_010_setting_up_a_spigot_server.md @@ -13,7 +13,7 @@ Buildtools also allows easy setup of many test environments since all you would need to do is to just change the version. -*Documented updated: 2023-01-14* +*Documented updated: 2023-07-24*
@@ -24,11 +24,11 @@ If you need more assistance, please search for online documentation since there are many good resources out there. * First install a copy of Java that is accessible from the command line. - - The current version of Java is version 17. Even if you are using jars and other plugins that were compiled with Java 1.8.x, it is recommended to use Java 17. - - If you feel like you must use Java 1.8, it's strongly suggested to use only the latest version 1.8.0_x. + - The current recommended version of Java is version 17. Even if you are using jars and other plugins that were compiled with Java 1.8.x, or older, it is recommended to use Java 17. + - If you feel like you must use Java 1.8, it's strongly suggested to use only the latest version 1.8.0_x since there are still current security releases. -* You can download it from [Sun SE Development Kit 8]https://www.oracle.com/java/technologies/javase/javase-jdk8-downloads.html) for product that you need. +* You can download it from [Sun SE Development Kit 8]https://www.oracle.com/java/technologies/javase/javase-jdk8-downloads.html) for a product that you need. * You can also use Open JDK if Sun's license does not fit your needs. [OpenJDK Install](https://openjdk.java.net/install/) @@ -61,6 +61,7 @@ there are many good resources out there. java -jar BuildTools.jar --rev 1.17.1 java -jar BuildTools.jar --rev 1.18.2 java -jar BuildTools.jar --rev 1.19.3 + java -jar BuildTools.jar --rev 1.20.1 ``` * For example, with BuildTools.jar being in a root directory, create a subdirectory and then start a build within that directory. The benefit is that you can use the same BuildTools.jar to build multiple different versions of spigot. This example starts off with building a v1.17.1 instance and then builds a 1.8.8 instance. Normally you wouldn't build multiple versions of spigot, but this shows how easy and flexible it is to build any version of spigot that has been released. @@ -79,7 +80,7 @@ there are many good resources out there. * **Updating BuildTools:** Once in a while you will be prompted to update the BuildTools.jar file. To do update it, all you need to do is to just download it, and replace the older one you were using. -* **Updating the built servers:** Every once in a while, when you are starting a server, there may be a notification that the server software needs to be update. Just rerun the BuildTools for the same version within the original build directory. The build tools will update all of the changed resources and then generate the new server jars that you copy to the actual server (see the next step). +* **Updating the built servers:** Every once in a while, when you are starting a server, there may be a notification that the server software needs to be update and the server startup will be paused for about 20 seconds. Just rerun the BuildTools for the same version within the original build directory. The build tools will update all of the changed resources and then generate the new server jars that you copy to the actual server (see the next step).
diff --git a/docs/prison_docs_012_setting_up_prison_basics.md b/docs/prison_docs_012_setting_up_prison_basics.md index 0dee13510..71d18ace3 100644 --- a/docs/prison_docs_012_setting_up_prison_basics.md +++ b/docs/prison_docs_012_setting_up_prison_basics.md @@ -7,7 +7,7 @@ This document provides a quick overview on how to install Prison and get it running. -*Documented updated: 2023-01-28* +*Documented updated: 2023-07-24*
@@ -18,9 +18,10 @@ This document provides a quick overview on how to install Prison and get it runn Download Prison from one of the following sites: * [spigotmc.org's Prison History Page](https://www.spigotmc.org/resources/prison.1223/history). -* [Polymart.org](https://polymart.org/resource/prison-1-8-x-1-17.678) +* [Polymart.org](https://polymart.org/resource/prison-1-8-x-1-20-x.678) * [bukkit.org](https://www.curseforge.com/minecraft/bukkit-plugins/mc-prison-v3) +These sites will have stable alpha releases published to them from time to time. Setting up Prison is simple: @@ -34,7 +35,7 @@ Setting up Prison is simple: - You can always find the latest alpha build on the Discord Server in the #alpha-versions channel: - [Prison Discord Server](https://discord.gg/DCJ3j6r) -* Copy the prison jar file to your server's plugin directory. +* Copy the prison jar file to your server's `/plugin` directory. * Remove any older prison jar file @@ -43,7 +44,7 @@ Setting up Prison is simple: * Prison's startup information contains a lot of information. If you ever have issues, check that information first since it probably will identify what the issues are. -* It is strongly suggested that `/ranks autoConfigure` is ran to initially setup your Prison environment. A great deal of configurations are setup that can save a lot of effort. Even if you are wanting to start from scratch, it may be worth giving it a try to see how some of the more complex settings are configured. You can always start over by deleting the `plugins/Prison/` directory. +* It is strongly suggested that `/ranks autoConfigure` is ran to initially setup your Prison environment. A great deal of configurations are setup that can save a lot of effort. Even if you are wanting to start from scratch, it may be worth giving it a try to see how some of the more complex settings are configured. You can always start over by deleting the `/plugins/Prison/` directory then restarting the server. * Follow Prison's documentation on customization; at this point it's ready for use. @@ -60,7 +61,7 @@ Setting up Prison is simple: There may be no hard dependencies that will prevent Prison from running, but there are some core plugins that will make it easier to use, and are even required for activation of some features within Prison. This short list is just a suggestion, but alternatives do exist and may be outside of our ability to comment or assist in their usage. -* **Vault** - Optional, but STRONGLY Suggested - This is perhaps the most important plugin. This plugin provides a common way to access other plugins running on your server, but without having to write any code within Prison to support them. Vault provides the mapping of a plugin's unique APIs to a common Vault API. Vault helps support Economy, Permissions, and Placeholders. Because of Vault, Prison can work flawlessly with dozens of other plugins. Please refer to Vault's documentation for what it supports. +* **Vault** - Optional, but **STRONGLY Suggested** - This is perhaps the most important plugin. This plugin provides a common way to access other plugins running on your server, but without having to write any code within Prison to support them. Vault provides the mapping of a plugin's unique APIs to a common Vault API. Vault helps support Economy, Permissions, and Placeholders. Because of Vault, Prison can work flawlessly with dozens of other plugins. Please refer to Vault's documentation for what it supports. Valut does have it's limitations, such as it can only support one currency at a time. * **EssentialsX** - **STRONGLY SUGGESTED**, but still Optional - Provides many of the basic commands and behaviors that you would expect from a Spigot server such as chat, warps, and even some moderation commands and commands that can be given to premium players. EssentialsX is not Essentials, since Essentials is an older abandoned project, and EssentialsX is a forked project that is still maintained. Unfortunately, internally it is identified as simply Essentials, but you can tell it's EssentialsX if the version is greater than 2.15.x. @@ -72,6 +73,8 @@ There may be no hard dependencies that will prevent Prison from running, but the Prison requires an active economy in order to active the Ranks plugin. When Prison starts up, it performs many validations on the mines and ranks as they are being loaded. With Ranks, if Prison cannot find an active economy, then it will refuse to load the Ranks module due to possible server corruption (ie... what failed that there is no economy). +We say an economy is required, but it's still optional. Without an economy, you cannot use the ranks module, but we fully understand that some servers choose to use a different ranks plugin. + * **EssentialsX Economy** - SUGGESTED - Optional - This is a simple economy plugin that just works well. If you don't have a specific need to use another economy plugin, then it may be best to use this one since it works so well. The reason why we recommend this economy is because it always works. That said, we acknowledge the reason it works well, is because it is so simple, so if there are features in other economy plugins that you want to use on your sever, then please explore using them. But overall, if you just want an economy that is rock solid, then EssentialsX's Economy is a great choice. @@ -163,13 +166,15 @@ All of Prison's placeholders have an alias. An alias is a shortened name for a **NOTE: Prison no longer supports MVdWPlaceholder** because it could not support all of the advanced features with placeholders that prison uses. Also, since prison generates so many possible placeholders, MVdW pollutes the console log with thousands of lines of useless information stating each variant of a placeholder has been registered. We also dropped support for this plugin because there is no way to contact the developer because they hide behind a pay-wall, and I'm not about to buy one of their other plugins to just tell them their so-called-free plugin is not working properly. -But perhaps the biggest reason why I dropped support for MVdW is because it's 100% pointless. **PlaceholderAPI** works flawlessly with MVdW so there is absolutely no reason why prison needs to support MVdW anymore. If you need to use MVdW, then please keep using it, it works great with their other plugins. But you can use PlaceholderAPI along with it too. So there are zero reasons why you cannot use PlaceholderAPI, and everyone is happy. +But perhaps the biggest reason why I dropped support for MVdW is because it's 100% pointless from Prison's perspective. **PlaceholderAPI** works flawlessly with MVdW installed too, so there is absolutely no reason why prison needs to support MVdW anymore since everything works perfectly through PlaceholderAPI. If you need to use MVdW, then please keep using it, it works great with their other plugins. But you can use PlaceholderAPI along with it too. So there are zero reasons why you cannot use PlaceholderAPI, and everyone is happy. ~~Suggested to Avoid - Prison does support this plugin, but since it is used mostly with premium plugins, we have no way to fully test this plugin to ensure it actually works correctly. We've heard very few people have used this plugin, but we've heard it does work well. Use at your own risk.~~ ~~With this plugin, all placeholders are registered with it automatically when prison starts up, and all placeholders should be used as all lower case. Because prison has so many placeholders, with many that are expanded based upon ladders, ranks, and mine names, a modest prison server could generate and register well over 1000 placeholders. MVdWPlaceholder appears to be very verbose so you will see a lot of logging in the console when it starts up.~~ -~~It should also be noted that because of some of the limitations of MVdW, not all features of Prison's placeholder support will be supported. For example, you may not be able to reload placeholders, or use placeholder attributes to customize how placeholders are used.~~ +~~It should also be noted that because of some of the limitations of MVdW, not all features of Prison's placeholder support will be supported. For example, you may not be able to reload placeholders, or use placeholder attributes to customize how placeholders are used. Also the numerical sequence placeholders may not work either.~~ + +~~Like it was said earlier, there is no way to contact the developers. If we could make just one suggestion, and that would be to allow setting up placeholders by specifying a prefix that's used. This is how PlaceholderAPI works, so with just registering once, a value of "prison_" that ensures all of prison's placeholders are routed to us. Also, make sure the allowable placeholders are not limited by length. Prison use placeholder attributes that can customize how the results are modified which gives an almost limitless opportunity to customize placeholders as desired to match the server's design standards. The third suggestion for changes is to allow the reloading of placeholders with a simple command, such as reregistering them. As admins add ranks, ladders, or mines, or even change their names, then all of the placeholders must be reregistered so the new entries are included.~~ @@ -243,7 +248,9 @@ Warning: People have paid for this plugin only to find out after the fact that i If you purchase this plugin to use on your server, do so with great caution since it is not supported and it may not integrate with prison. [ * Not supported * Tokens * Not supported * ](https://www.spigotmc.org/resources/%E2%9A%A1%EF%B8%8F-tokens-%E2%9A%A1%EF%B8%8F-40-enchantments-%E2%AD%95-free-expansions-%E2%AD%95-25-off.79668/) -**Please Note:** There is another plugin by the same name "Tokens" that strictly deals with tokens and not enchantments, which works just fine with prison. + +**Please Note:** There is another plugin by the same name "Tokens" that strictly deals with tokens and not enchantments, which works just fine with prison. I have even personally contributed to that plugin to provide caching of the player's data to resolve an issue with ultra fast mining in prison. Basically it used to be that if you give players tokens too quickly, it would lockup the server trying to update the save files. Now it easily supports 100's, if not 1000's of transactions per second without any impact to the TPS. + ### Enchantment Plugin Features Supported @@ -461,15 +468,16 @@ Once entered, it will enable the following submit tools: `/prison support submit` - Show the available tools. ``` +/prison support submit version /prison support submit configs /prison support submit latestLogs /prison support submit mines /prison support submit ranks -/prison support submit version ``` -Here is an example that I generated from one of my test servers on 2021-12-03. I have no idea how long the content remains available, but for support purposes, we only need this information for a few hours. - [https://paste.helpch.at/itejovejeh](https://paste.helpch.at/itejovejeh) +Here is an example that I generated from one of my test servers on 2021-12-03. I have no idea how long the content remains available, but for support purposes, we only need this information for a few hours. It appears like this information is never deleted? As such, here are two different versions which shows you how much more information has been addeed. + [https://paste.helpch.at/silihuxaja](https://paste.helpch.at/silihuxaja) From Prison v3.3.0-alpha.15a + [https://paste.helpch.at/itejovejeh](https://paste.helpch.at/itejovejeh) From Prison v3.2.11-alpha.9 # Prison Commands diff --git a/docs/prison_docs_013_Prison_Help.md b/docs/prison_docs_013_Prison_Help.md index f6d6bd04e..353dfa148 100644 --- a/docs/prison_docs_013_Prison_Help.md +++ b/docs/prison_docs_013_Prison_Help.md @@ -13,6 +13,10 @@ This document provides some important information on how to find help in setting # Overview +We take support seriously. We realize that being a Prison plugin, we are working with a lot of different aspects of minecraft, and that there are many other plugins that may cross paths with Prison. We cannot support every single plugin out there, but we will try to resolve and identify all problems that are brought to our attention.. + +Because we are so very concerned with your server's functionality, we have put a lot of effort in trying to create support tools to better understand what is happening. We cannot control other plugins, but prison is capable of tracking and reporting many fine-grained details about how it works and what is happening step-by-step. This can allow us to figure out difficult problems. + If you are having problem, please take a quick look at the following documents as found in the Table of Contents: * Setting up prison and various plugins - If special conditions for their configurations become apparent in order for prison to work, notes will be added there. If you notice there is a special configuration consideration that we did not document, please share with us so we can update the documents. @@ -129,6 +133,77 @@ You can also submit a help ticket on the Prison github Issues tab, but the respo + +# Prison Support Submit Information + +Prison now has a built in way to share your configurations and settings with support personnel. + +More information will be documented in the future, but for now, here are the basics on how to use it. + +When requested by the Prison support team, you would first enter the following command to set your name that will be included on all reports to help identify who the are related to. It doesn't have to be your full discord name, but enough characters to allow us to identify who you are. + + +These commands will collect all of the related information from your Prison setup, and send it to the website `https://paste.helpch.at`. It will provide you with an URL. All you need to do is to copy and paste that URL in to the discord chat so the Prison support team can help with your issue. + + +`/prison support setSupportName ` + +Once entered, it will enable the following submit tools: + +`/prison support submit` - Show the available tools. + +``` +/prison support submit version +/prison support submit ranks +/prison support submit mines +/prison support submit configs +/prison support submit listeners +/prison support submit latestLogs +``` + +**Version** This is generally the most requested information needed for support. Provides general overall information on Prison and it's environment on the server. This is similar to the command `/prison version all` plus a few other features such as listeners, and the command cache. + +**Ranks** This is everything related to ranks. Includes ladders, ranks lists, and rank details. It also includes all of the raw save file for these items too. + +**Mines** This is everything related to mines. Includes the mine list, mine info, and the related files for each mine. + +**Configs** These are all of the other config files that are within prison. These do not include any of the files included in ranks or mines. + +**Listeners** These are dumps of the event listeners for BlockBreak, chat, and playerinteract. See the command `/prison support listeners help` for more detailed information. + +**LatestLogs** This will send the latest log file, up to a max allowed amount. + + +Here are two examples that I generated from one of my test servers on 2021-12-03 and 2023-07-24. I have no idea how long the content remains available, but for support purposes, we only need this information for a few hours. It appears like this information is never deleted? As such, here are two different versions which shows you how much more information has been added. + [https://paste.helpch.at/silihuxaja](https://paste.helpch.at/silihuxaja) From Prison v3.3.0-alpha.15a + [https://paste.helpch.at/itejovejeh](https://paste.helpch.at/itejovejeh) From Prison v3.2.11-alpha.9 + + +# Prison Support HTML Output Files + +As a brand new feature, Prison now is able to generate HTML files that are stored within the `plugins/Prison/backups/` directory. It includes information from version, ranks, mines, listeners, and configs. See above. The nice thing about this support format is that it reproduces all of the colors as found in the console version of these commands. + +This file format is also good for server owners who do not want to post their server information on another website. + +To generate the file, use the command: +`/prison support saveToFile help` + +To generate with the defaults settings: +`/prison support saveToFile basic` + +If an existing file exists, it will generate the next one in the series. When ran, it will identify what the current file is. Please send this file to support. + + + +If you want to use this format instead of the above file that are sent to paste.helpch.at, then generate the file and you can DM it to either Blue or Madog. It's best to ask before sending to confirm we are available to respond to your needs. + + +NOTE: Hyperlinks and table of contents will be added to this HTML support document. + + +
+ + # Prison Debugger diff --git a/docs/prison_docs_101_setting_up_mines.md b/docs/prison_docs_101_setting_up_mines.md index e116ed6db..15594f294 100644 --- a/docs/prison_docs_101_setting_up_mines.md +++ b/docs/prison_docs_101_setting_up_mines.md @@ -15,6 +15,9 @@ This document provides some highlights to how to setup mines. It is a work in p This document should be able to provide the basic information to get your mines configured. There are many options available within Prison, and also through the use of other plugins, so advanced topics that blend multiple plugins, and their various settings, are beyond the scope of this document. +As a side note, if you installed prison, and it appears like it may not be working in a specific world, please see the `config.yml` file to see if prison's command handler is disabled within that world. If it is, then all prison commands will be turned off in that world, and there will be no way to bypass it unless the config.yml file is changed. + + Prison has a list of suggested plugins that works well with Prison, and a few that do not work at all with Prison. Please see the following document for a list of suggested plugins. If you have a favorite plugin that works well with Prison and it's not in that list, then please reach out to us in our discord server and make a suggestion for it to be added. [Setting up Prison - The Basics](prison_docs_012_setting_up_prison_basics.md) @@ -249,7 +252,11 @@ Some of the highlights of these commands are as follows: * `/mines set liner` : A quick way to wrap your mine with a 2D Pattern in 3D space. This command also will `repair` the area around a mine, and will effectively erase a liner. There are six directions that can be specified for change: `north`, `south`, `east`, `west`, `top`, and `bottom`. `walls` also is a shortcut for `north`, `south`, `east`, and `west`. The patterns available are listed by the command. There is even a `force` setting that will allow the mine to be wrapped when in air, since the wrappings normally needs blocks in contact with the mine so it is able to conform to the terrain. + + * `/mines set mineSweeper` : If all else fails to get Prison to monitor and track blocks that are broken within a mine, mostly due to conflicts with other plugins, then this option can provide a last chance effort to monitor the progress within a mine. It is very rare that you would have to use this setting and the chances are that there are better ways to get the mines working correctly. The larger the mine, the more costly this setting is to enable. + + * **Removed:** `/mines set move` is a new command that is not yet enabled. It is still in development, but will be active soon. This command will move a whole mine as a single unit, be it a few blocks or many (not recommended). The same effect of moving a mine can be done through the command: `/mine set size` but note it will possibly damage or destory the surrounding builds if not careful. * **Removed:** `/mines set norank` : Disconnect the mine from a rank. **Note:** This command has been changed to `/mines set rank *none*` to delete the rank from the mine. @@ -266,7 +273,11 @@ Some of the highlights of these commands are as follows: * `/mines set sortOrder` : Mines can be sorted for view within `/mines list` or the GUI. Setting the sortOrder allows you manually set the order in which the mines are listed. There is even the option to suppress (hide) mines from that list too by setting the sort order to a -1. * `/mines set spawn` : Sets the mines spawn point. Whatever you are looking at is what the players will be looking at when they tp to that spot. * `/mines set tag` : Set a mine tag value that can be used with placeholders. -* `/mines set tracer` : Removes all blocks in a mine and replaces them with air, with the exception of the corners, of which are replace with pink_stained_glass. This function allows for easy viewing of the full mine without the blocks getting in the way. It also helps when setting the liner of the mine. Using `/mines reset` returns the mine to normal functionality, or it will reset on its own. + + +* `/mines set tracer help` : Removes all blocks in a mine and replaces them with air. This is good to allow you to access and work on the liners or ladders. There are three options with this command: `outline`, `corners` and `clear`. The option `outline` is the default and will use this option unless the others are specified. `outline` will apply pink glass blocks along the outline of the mine. `corners` will only place pink stained glass blocks in the 8 corners of the mine. And `clear` will add no tracers and will result in a fully cleared mine. This function allows for easy viewing of the full mine without the blocks getting in the way. It also helps when setting the liner of the mine. Using `/mines reset` returns the mine to normal functionality, or it will reset on its own. + +. * `/mines set zeroBlockResetDelay` : If the mine runs out of blocks, when enabled, it will force a manual reset after the specified delay. The delay can be zero for instant reset. diff --git a/docs/prison_docs_111_mine_commands.md b/docs/prison_docs_111_mine_commands.md index 6f11fbc15..346b73749 100644 --- a/docs/prison_docs_111_mine_commands.md +++ b/docs/prison_docs_111_mine_commands.md @@ -29,7 +29,7 @@ My personal goals to use this new feature was to dynamically build a large fores The family of mine commands are as follows: ``` -/mines command +/mines ``` Mine Commands From d66d47c37cf1cb7c5afd1a6bdfccb093b3ccc8fe Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Thu, 27 Jul 2023 18:57:57 -0400 Subject: [PATCH 046/151] TopN: TopN was not being disabled correctly for when ranks were disabled. This now properly checks the PrisonRanks to see if the ranks module is active or not. The prior code was not being as detailed. --- docs/changelog_v3.3.x.md | 6 +++- .../prison/ranks/data/TopNPlayers.java | 28 ++++++++++++++----- 2 files changed, 26 insertions(+), 8 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 45c9836c5..0524cef95 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -14,7 +14,11 @@ These change logs represent the work that has been going on within prison. -# 3.3.0-alpha.15a 2023-07-24 +# 3.3.0-alpha.15a 2023-07-27 + + +* **TopN: TopN was not being disabled correctly for when ranks were disabled.** +This now properly checks the PrisonRanks to see if the ranks module is active or not. The prior code was not being as detailed. * **Prison support: Added more color related test. Changed the color schema name from 'madog' to 'prison'.** diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/TopNPlayers.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/TopNPlayers.java index be8763fd6..b11021aae 100644 --- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/TopNPlayers.java +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/TopNPlayers.java @@ -130,7 +130,9 @@ public File getSaveFile() { */ private void launchTopNPlayerUpdateAsyncTask() { - if ( PrisonRanks.getInstance().getPlayerManager() != null ) { + if ( PrisonRanks.getInstance() != null && + PrisonRanks.getInstance().isEnabled() && + PrisonRanks.getInstance().getPlayerManager() != null ) { Long delayTicks = Prison.get().getPlatform().getConfigLong( "topNPlayers.refresh.delay-ticks", DELAY_THIRTY_SECONDS_TICKS ); @@ -169,7 +171,9 @@ private void launchTopNPlayerUpdateAsyncTask() { public void loadSaveFile() { // If Ranks module is not loaded, then do not try to load any save file: - if ( PrisonRanks.getInstance().getPlayerManager() == null ) { + if ( PrisonRanks.getInstance() == null || + !PrisonRanks.getInstance().isEnabled() || + PrisonRanks.getInstance().getPlayerManager() == null ) { // Ranks is not loaded, so reset to empties: setTopNList( new ArrayList<>() ); @@ -242,7 +246,9 @@ public void loadSaveFile() { */ public void forceReloadAllPlayers() { - if ( PrisonRanks.getInstance().getPlayerManager() != null ) { + if ( PrisonRanks.getInstance() != null && + PrisonRanks.getInstance().isEnabled() && + PrisonRanks.getInstance().getPlayerManager() != null ) { long start = System.nanoTime(); @@ -380,7 +386,9 @@ private void addPlayerData( TopNPlayersData topN, PlayerState activePlayerState public void refreshAndSort() { - if ( PrisonRanks.getInstance().getPlayerManager() == null ) { + if ( PrisonRanks.getInstance() == null || + !PrisonRanks.getInstance().isEnabled() || + PrisonRanks.getInstance().getPlayerManager() == null ) { return; } @@ -491,7 +499,9 @@ public void refreshAndSort() { private void calculateAllRankScores( ArrayList topNList ) { - if ( PrisonRanks.getInstance().getPlayerManager() != null ) { + if ( PrisonRanks.getInstance() != null && + PrisonRanks.getInstance().isEnabled() && + PrisonRanks.getInstance().getPlayerManager() != null ) { for ( TopNPlayersData topN : topNList ) { @@ -590,7 +600,9 @@ else if ( getArchivedMap().containsKey( key ) ) { */ public void updatePlayerData( RankPlayer rPlayer ) { - if ( PrisonRanks.getInstance().getPlayerManager() != null ) { + if ( PrisonRanks.getInstance() != null && + PrisonRanks.getInstance().isEnabled() && + PrisonRanks.getInstance().getPlayerManager() != null ) { addPlayerData( rPlayer); @@ -662,7 +674,9 @@ public RankPlayer getTopNRankArchivedPlayer( int rankPosition ) { private RankPlayer getTopNRankPlayer( int rankPosition, boolean archived ) { RankPlayer rPlayer = null; - if ( PrisonRanks.getInstance().getPlayerManager() != null ) { + if ( PrisonRanks.getInstance() != null && + PrisonRanks.getInstance().isEnabled() && + PrisonRanks.getInstance().getPlayerManager() != null ) { ArrayList tList = archived ? From 3db2cf4117333539655585005d34ce4cee44a9d1 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Fri, 28 Jul 2023 09:39:43 -0400 Subject: [PATCH 047/151] Fixed an issue with BRICKS being mismatched to BRICK. This is an XSeries bug. --- docs/changelog_v3.3.x.md | 5 ++++- .../tech/mcprison/prison/spigot/compat/Spigot18Blocks.java | 5 +++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 0524cef95..87f8fd4c7 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -14,7 +14,10 @@ These change logs represent the work that has been going on within prison. -# 3.3.0-alpha.15a 2023-07-27 +# 3.3.0-alpha.15a 2023-07-28 + + +* **Fixed an issue with BRICKS being mismatched to BRICK. This is an XSeries bug.** * **TopN: TopN was not being disabled correctly for when ranks were disabled.** diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot18Blocks.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot18Blocks.java index 8594d6924..96892420a 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot18Blocks.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot18Blocks.java @@ -275,10 +275,15 @@ public XMaterial getXMaterial( PrisonBlock prisonBlock ) { results = XMaterial.matchXMaterial( blockName ).orElse( null ); + // Convert items to their block representation: if ( results == XMaterial.MELON_SLICE && prisonBlock.getBlockName().equalsIgnoreCase( "melon" ) ) { results = XMaterial.MELON; } + else if ( results == XMaterial.BRICK && + prisonBlock.getBlockName().equalsIgnoreCase( "bricks" ) ) { + results = XMaterial.BRICKS; + } putCachedXMaterial( prisonBlock, results ); } From 2891ac831493e955acd7744ed6e84e598c539671 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Fri, 28 Jul 2023 09:41:17 -0400 Subject: [PATCH 048/151] v3.3.0-alpha.15b 2023-07-28 --- docs/changelog_v3.3.x.md | 6 +++++- gradle.properties | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 87f8fd4c7..0f7061b95 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -14,7 +14,11 @@ These change logs represent the work that has been going on within prison. -# 3.3.0-alpha.15a 2023-07-28 +# 3.3.0-alpha.15b 2023-07-28 + + + +**v3.3.0-alpha.15b 2023-07-28** * **Fixed an issue with BRICKS being mismatched to BRICK. This is an XSeries bug.** diff --git a/gradle.properties b/gradle.properties index 9daf50886..9aa660bdb 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,7 +3,7 @@ ## # This is actually the "correct" place to define the version for the project. ## # Used within build.gradle with ${project.version}. ## # Can be overridden on the command line: gradle -Pversion=3.2.1-alpha.3 -version=3.3.0-alpha.15a +version=3.3.0-alpha.15b From 795a851e5323189ac8cd7acc2494dcba7767f40d Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Fri, 28 Jul 2023 11:44:50 -0400 Subject: [PATCH 049/151] Mine Bombs: Found an issue with the bomb settings for allowedMines and preventMines, and fixed it. There is a global setting in config.yml under the settings: `prison-mines.mine-bombs.prevent-usage-in-mines` to disable all mine bombs from working in those mines. The bombs can then be individually added by setting adding mine names to the bomb configs settings for `allowedMines` and `preventedMines`. If a mine is included on a bomb's allowedMines setting, it will override any global setting. --- docs/changelog_v3.3.x.md | 4 ++ .../mcprison/prison/bombs/MineBombData.java | 8 +++ .../bombs/MineBombDefaultConfigSettings.java | 7 +++ .../tech/mcprison/prison/bombs/MineBombs.java | 26 +++++++-- .../prison/bombs/MineBombsConfigData.java | 2 +- .../prison/internal/platform/Platform.java | 2 + .../tech/mcprison/prison/TestPlatform.java | 7 +++ .../prison/spigot/SpigotPlatform.java | 54 ++++++++++++------- 8 files changed, 88 insertions(+), 22 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 0f7061b95..2e63b4e31 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -21,6 +21,10 @@ These change logs represent the work that has been going on within prison. **v3.3.0-alpha.15b 2023-07-28** +* **Mine Bombs: Found an issue with the bomb settings for allowedMines and preventMines, and fixed it.** +There is a global setting in config.yml under the settings: `prison-mines.mine-bombs.prevent-usage-in-mines` to disable all mine bombs from working in those mines. The bombs can then be individually added by setting adding mine names to the bomb configs settings for `allowedMines` and `preventedMines`. If a mine is included on a bomb's allowedMines setting, it will override any global setting. + + * **Fixed an issue with BRICKS being mismatched to BRICK. This is an XSeries bug.** diff --git a/prison-core/src/main/java/tech/mcprison/prison/bombs/MineBombData.java b/prison-core/src/main/java/tech/mcprison/prison/bombs/MineBombData.java index fee24d4e1..d341e3b8c 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/bombs/MineBombData.java +++ b/prison-core/src/main/java/tech/mcprison/prison/bombs/MineBombData.java @@ -309,6 +309,14 @@ public MineBombData clone() { cloned.getLore().add( l ); } + for ( String mine : getAllowedMines() ) { + cloned.getAllowedMines().add( mine ); + } + + for ( String mine : getPreventedMines() ) { + cloned.getPreventedMines().add( mine ); + } + for ( MineBombEffectsData soundEffect : getSoundEffects() ) { diff --git a/prison-core/src/main/java/tech/mcprison/prison/bombs/MineBombDefaultConfigSettings.java b/prison-core/src/main/java/tech/mcprison/prison/bombs/MineBombDefaultConfigSettings.java index 89494b456..ef03e2c9b 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/bombs/MineBombDefaultConfigSettings.java +++ b/prison-core/src/main/java/tech/mcprison/prison/bombs/MineBombDefaultConfigSettings.java @@ -219,6 +219,13 @@ public void setupDefaultMineBombData(MineBombs mineBombs) mbd.setToolInHandFortuneLevel( 0 ); mbd.setRemovalChance( 40.0d ); + mbd.getAllowedMines().add( "a" ); + mbd.getAllowedMines().add( "b" ); + mbd.getAllowedMines().add( "c" ); + + mbd.getPreventedMines().add( "d" ); + mbd.getPreventedMines().add( "e" ); + mbd.getSoundEffects().add( mbeSound01.clone() ); mbd.getSoundEffects().add( mbeSound02.clone().setOffsetTicks( 30 ) ); mbd.getSoundEffects().add( mbeSound03.clone() ); diff --git a/prison-core/src/main/java/tech/mcprison/prison/bombs/MineBombs.java b/prison-core/src/main/java/tech/mcprison/prison/bombs/MineBombs.java index ce3df4b73..eb22b99c9 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/bombs/MineBombs.java +++ b/prison-core/src/main/java/tech/mcprison/prison/bombs/MineBombs.java @@ -147,9 +147,12 @@ public void loadConfigJson() { File configFile = getConfigFile( fio ); - if ( !configFile.exists() ) { + boolean configExists = configFile.exists(); + + if ( !configExists ) { MineBombDefaultConfigSettings defaultConfigs = new MineBombDefaultConfigSettings(); defaultConfigs.setupDefaultMineBombData( this ); + } else { @@ -192,8 +195,25 @@ public void loadConfigJson() { } } + } + + + StringBuilder sbMsg = new StringBuilder(); + int cnt = getConfigData().getBombs().size(); + sbMsg.append( "Prison Mine Bombs: " ) + .append( cnt ) + .append( "[" ); + + for ( String key : getConfigData().getBombs().keySet() ) { + MineBombData bomb = getConfigData().getBombs().get( key ); + sbMsg.append( " " ) + .append( bomb.getName() ); } + + sbMsg.append( " ]" ); + + Output.get().logInfo( sbMsg.toString() ); } @@ -369,7 +389,7 @@ public void validateMineBombs() cleaned = true; } - if ( !Prison.get().getPlatform().getMinesListString().contains(cleanName) ) { + if ( !Prison.get().getPlatform().isMineNameValid(cleanedMineName) ) { Output.get().log( "MineBomb %s: invalid mine name for allowedMines: %s Removed.", LogLevel.WARNING, bomb.getName(), cleanedMineName ); @@ -399,7 +419,7 @@ public void validateMineBombs() cleaned = true; } - if ( !Prison.get().getPlatform().getMinesListString().contains(cleanName) ) { + if ( !Prison.get().getPlatform().isMineNameValid(cleanedMineName) ) { Output.get().log( "MineBomb %s: invalid mine name for prevented-Mines: %s Removed.", LogLevel.WARNING, bomb.getName(), cleanedMineName ); diff --git a/prison-core/src/main/java/tech/mcprison/prison/bombs/MineBombsConfigData.java b/prison-core/src/main/java/tech/mcprison/prison/bombs/MineBombsConfigData.java index fd45845b1..4c34d0b99 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/bombs/MineBombsConfigData.java +++ b/prison-core/src/main/java/tech/mcprison/prison/bombs/MineBombsConfigData.java @@ -16,7 +16,7 @@ public class MineBombsConfigData * data. *

*/ - public static final int MINE_BOMB_DATA_FORMAT_VERSION = 1; + public static final int MINE_BOMB_DATA_FORMAT_VERSION = 2; private int dataFormatVersion = 1; diff --git a/prison-core/src/main/java/tech/mcprison/prison/internal/platform/Platform.java b/prison-core/src/main/java/tech/mcprison/prison/internal/platform/Platform.java index 3249ca241..d0ac90ea1 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/internal/platform/Platform.java +++ b/prison-core/src/main/java/tech/mcprison/prison/internal/platform/Platform.java @@ -388,6 +388,8 @@ public void autoCreateMineLinerAssignment( List rankMineNames, public void saveResource( String string, boolean replace ); + + public boolean isMineNameValid(String mineName); public String getMinesListString(); diff --git a/prison-core/src/test/java/tech/mcprison/prison/TestPlatform.java b/prison-core/src/test/java/tech/mcprison/prison/TestPlatform.java index 5d7b08063..a1d5ca6d6 100644 --- a/prison-core/src/test/java/tech/mcprison/prison/TestPlatform.java +++ b/prison-core/src/test/java/tech/mcprison/prison/TestPlatform.java @@ -434,6 +434,13 @@ public void saveResource( String string, boolean replace ) { } + + @Override + public boolean isMineNameValid(String mineName) { + return false; + } + + @Override public String getMinesListString() { return ""; diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/SpigotPlatform.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/SpigotPlatform.java index 5920c43a5..13603d703 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/SpigotPlatform.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/SpigotPlatform.java @@ -2872,29 +2872,47 @@ public void saveResource( String fileName, boolean replace ) { SpigotPrison.getInstance().saveResource( fileName, replace ); } - @Override - public String getMinesListString() { + public boolean isMineNameValid( String mineName ) { + boolean results = false; + if ( PrisonMines.getInstance().isEnabled() ) { + + Mine mine = PrisonMines.getInstance().getMine(mineName); + + results = mine != null; + } - MinesCommands mc = PrisonMines.getInstance().getMinesCommands(); + return results; + } + + @Override + public String getMinesListString() { + String results = ""; - - ChatDisplay display = new ChatDisplay("Mines"); - - display.addSupportHyperLinkData( "Mines List" ); - - // get the mine list: - mc.getMinesList( display, MineManager.MineSortOrder.sortOrder, "all", null ); - - StringBuilder sb = display.toStringBuilder(); - - sb.append( "\n" ); - - // get the mine details for all mines: - mc.allMinesInfoDetails( sb ); + if ( PrisonMines.getInstance().isEnabled() ) { + + MinesCommands mc = PrisonMines.getInstance().getMinesCommands(); + + + ChatDisplay display = new ChatDisplay("Mines"); + + display.addSupportHyperLinkData( "Mines List" ); + + // get the mine list: + mc.getMinesList( display, MineManager.MineSortOrder.sortOrder, "all", null ); + + StringBuilder sb = display.toStringBuilder(); + + sb.append( "\n" ); + + // get the mine details for all mines: + mc.allMinesInfoDetails( sb ); + + results = sb.toString(); + } - return sb.toString(); + return results; // return Text.stripColor( sb.toString() ); } From ff7b39f80f03192687b8c4eac4f2692505d21005 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Fri, 28 Jul 2023 12:07:38 -0400 Subject: [PATCH 050/151] Prevent a NPE if the target block is not found within the mine's settings. --- docs/changelog_v3.3.x.md | 3 +++ .../mcprison/prison/spigot/block/OnBlockBreakEventCore.java | 1 + 2 files changed, 4 insertions(+) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 2e63b4e31..d4dee79a0 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -21,6 +21,9 @@ These change logs represent the work that has been going on within prison. **v3.3.0-alpha.15b 2023-07-28** +* **Prevent a NPE if the target block is not found within the mine's settings.** + + * **Mine Bombs: Found an issue with the bomb settings for allowedMines and preventMines, and fixed it.** There is a global setting in config.yml under the settings: `prison-mines.mine-bombs.prevent-usage-in-mines` to disable all mine bombs from working in those mines. The bombs can then be individually added by setting adding mine names to the bomb configs settings for `allowedMines` and `preventedMines`. If a mine is included on a bomb's allowedMines setting, it will override any global setting. diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/block/OnBlockBreakEventCore.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/block/OnBlockBreakEventCore.java index 760da3281..9468458af 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/block/OnBlockBreakEventCore.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/block/OnBlockBreakEventCore.java @@ -407,6 +407,7 @@ protected boolean validateEvent( PrisonMinesBlockBreakEvent pmEvent ) // and the block has not been mined before, then allow the breakage by // setting bypassMatchedBlocks to true to allow normal processing: if ( !matchedBlocks && + targetBlock != null && !targetBlock.isMined() && sBlockHit.isAir() && pmEvent.getBbPriority().isMonitor() ) { From b2c8c76bc8332ed901654c46f86cfdcbf6a0112f Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Fri, 28 Jul 2023 21:31:05 -0400 Subject: [PATCH 051/151] Sellall: clean up some of the help for a few sellall features and expand on the details. --- docs/changelog_v3.3.x.md | 3 + .../commands/PrisonSpigotSellAllCommands.java | 57 ++++++++++++------- 2 files changed, 40 insertions(+), 20 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index d4dee79a0..1304ba1ef 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -17,6 +17,8 @@ These change logs represent the work that has been going on within prison. # 3.3.0-alpha.15b 2023-07-28 +* **Sellall: clean up some of the help for a few sellall features and expand on the details. ** + **v3.3.0-alpha.15b 2023-07-28** @@ -90,6 +92,7 @@ The server has been down for the last two days and so other errors need to be ca A specific mine bomb can have a list of included mines, which overrides any exclusions. The mine bombs can be excluded from specific mines too. There is also a global disallowed mine list that will apply to all mine bombs, its in the config.yml file with the setting name of: prison-mines.mine-bombs.prevent-usage-in-mines +There is a global setting in config.yml under the settings: `prison-mines.mine-bombs.prevent-usage-in-mines` to disable all mine bombs from working in those mines. The bombs can then be individually added by setting adding mine names to the bomb configs settings for `allowedMines` and `preventedMines`. If a mine is included on a bomb's allowedMines setting, it will override any global setting. * **The Platform function getConfigStringArray should be a List of Strings for the return value, so updated the result type to reflect the correct setting.** diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/commands/PrisonSpigotSellAllCommands.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/commands/PrisonSpigotSellAllCommands.java index 292d23814..84a79c46b 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/commands/PrisonSpigotSellAllCommands.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/commands/PrisonSpigotSellAllCommands.java @@ -84,7 +84,8 @@ private void sellAllCurrency(CommandSender sender, } } - @Command(identifier = "sellall", description = "SellAll main command", + @Command(identifier = "sellall", + description = "SellAll main command", altPermissions = {"-none-", "prison.admin"}, onlyPlayers = false) private void sellAllCommands(CommandSender sender) { @@ -164,28 +165,34 @@ private void sellAllDelaySet(CommandSender sender, } } - @Command(identifier = "sellall autosell", description = "Enable SellAll AutoSell.", + @Command(identifier = "sellall autosell", + description = "Enable SellAll AutoSell. " + + "For AutoFeatures based sellall, please see the AutoFeatures configs.", onlyPlayers = false, permissions = "prison.autosell.edit") private void sellAllAutoSell(CommandSender sender, - @Arg(name = "boolean", description = "True to enable or false to disable.", def = "null") String enable){ + @Arg(name = "boolean", + description = "'True' to enable or 'false' to disable. Use 'perUserToggleable' to " + + "enable with users being able to turn on/off. Default value is 'true'. " + + "[true false perUserToggleable]", + def = "true") String enable){ if (!isEnabled()) return; + + SellAllUtil sellAllUtil = SellAllUtil.get(); + if (sellAllUtil == null){ + return; + } if (enable.equalsIgnoreCase("perusertoggleable")){ sellAllAutoSellPerUserToggleable(sender, enable); return; } - if (!(enable.equalsIgnoreCase("true") || enable.equalsIgnoreCase("false"))){ + if (!enable.equalsIgnoreCase("true") && !enable.equalsIgnoreCase("false") ){ Output.get().sendWarn(sender, messages.getString(MessagesConfig.StringID.spigot_message_sellall_boolean_input_invalid)); return; } - SellAllUtil sellAllUtil = SellAllUtil.get(); - if (sellAllUtil == null){ - return; - } - boolean enableBoolean = getBoolean(enable); if (sellAllUtil.isAutoSellEnabled == enableBoolean){ if (enableBoolean){ @@ -205,20 +212,27 @@ private void sellAllAutoSell(CommandSender sender, } } - @Command(identifier = "sellall autosell perUserToggleable", description = "Enable AutoSell perUserToggleable.", + @Command(identifier = "sellall autosell perUserToggleable", + description = "Enable AutoSell perUserToggleable. This will " + + "enable autosell if it's not already enabled, plus it will allow players to " + + "turn autosell on/off when they need to using the command `/sellall auto toggle`. " + + "If user toggleable is disabled through this command, it will also disable " + + "autosell, so you may need to turn it back on with `/sellall autosell true`.", onlyPlayers = false, permissions = "prison.autosell.edit") private void sellAllAutoSellPerUserToggleable(CommandSender sender, - @Arg(name = "boolean", description = "True to enable or false to disable", def = "null") String enable){ + @Arg(name = "boolean", + description = "'True' to enable or 'false' to disable. [true false]", + def = "") String enable){ if (!isEnabled()) return; - - if (!(enable.equalsIgnoreCase("true") || enable.equalsIgnoreCase("false"))){ - Output.get().sendWarn(sender, messages.getString(MessagesConfig.StringID.spigot_message_sellall_boolean_input_invalid)); - return; - } - + SellAllUtil sellAllUtil = SellAllUtil.get(); if (sellAllUtil == null){ + return; + } + + if ( !enable.equalsIgnoreCase("true") && !enable.equalsIgnoreCase("false") ) { + Output.get().sendWarn(sender, messages.getString(MessagesConfig.StringID.spigot_message_sellall_boolean_input_invalid)); return; } @@ -246,8 +260,8 @@ public void sellAllSellCommand(CommandSender sender, @Arg(name = "player", def = "", description = "An online player name to sell their inventory - " + "Only console or prison commands can include this parameter") String playerName, @Arg(name = "notification", def="", - description = "Notification about the sellall transaction. Defaults to normal. " + - "'silent' suppresses results. [silent]") String notification ){ + description = "Notification behavior for the sellall transaction. Defaults to normal. " + + "'silent' suppresses all notifications. [silent]") String notification ){ if (!isEnabled()) return; @@ -559,7 +573,10 @@ public void sellAllSellWithDelayCommand(CommandSender sender){ } - @Command(identifier = "sellall auto toggle", description = "Let the user enable or disable sellall auto", + @Command(identifier = "sellall auto toggle", + description = "When `perUserToggleable` is enabled with autosell, this " + + "command allow the players to enable or disable their own use of autosell. " + + "When using this command, autosell will be toggled on/off for the player.", altPermissions = "prison.sellall.toggle", onlyPlayers = true) private void sellAllAutoEnableUser(CommandSender sender){ From 1d6fb325bae5fd805a4c57676b1a962e97d8737e Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 29 Jul 2023 19:01:55 -0400 Subject: [PATCH 052/151] sellall & autosell: auto sell was not working correctly within auto manager. Also fixed the user toggle on auto sell so players can turn off autosell when they need to. --- docs/changelog_v3.3.x.md | 6 +- .../autofeatures/AutoManagerFeatures.java | 54 +++++++++---- .../spigot/block/OnBlockBreakEventCore.java | 19 +++-- .../commands/PrisonSpigotSellAllCommands.java | 5 +- .../prison/spigot/sellall/SellAllUtil.java | 80 +++++++++++++++---- 5 files changed, 126 insertions(+), 38 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 1304ba1ef..9c60f0c5b 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -14,7 +14,11 @@ These change logs represent the work that has been going on within prison. -# 3.3.0-alpha.15b 2023-07-28 +# 3.3.0-alpha.15b 2023-07-29 + + +* **sellall & autosell: auto sell was not working correctly within auto manager.** +Also fixed the user toggle on auto sell so players can turn off autosell when they need to. * **Sellall: clean up some of the help for a few sellall features and expand on the details. ** diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerFeatures.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerFeatures.java index 4257391c5..122576d55 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerFeatures.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerFeatures.java @@ -839,23 +839,34 @@ protected int autoPickup( PrisonMinesBlockBreakEvent pmEvent, long nanoTime = 0L; - boolean isSellallEnabled = SpigotPrison.getInstance().isSellAllEnabled(); + boolean isSellallEnabled = SellAllUtil.get() != null && + SpigotPrison.getInstance().isSellAllEnabled(); - // This is true if the player cannot toggle the autosell, and it's - // true if they can, and the have it enabled: - boolean isPlayerAutosellEnabled = isSellallEnabled && - SellAllUtil.get() != null && - SellAllUtil.get().checkIfPlayerAutosellIsActive( - pmEvent.getSpigotPlayer().getWrapper() ) - ; + // This will return true (allow autosell) unless players can toggle autosell and they turned it off: + // This is to be used with other auto sell setting, but never on it's own: + boolean isPlayerAutosellEnabled = + isSellallEnabled && + (!SellAllUtil.get().isAutoSellPerUserToggleable || + SellAllUtil.get().isSellallPlayerUserToggleEnabled( + pmEvent.getSpigotPlayer().getWrapper() )); + + // In the event, forceAutoSell is enabled, which means the drops must be sold. + // The player's toggle cannot disable this. boolean forceAutoSell = isSellallEnabled && pmEvent.isForceAutoSell(); - boolean autoSellBySettings = isSellallEnabled && isBoolean(AutoFeatures.isAutoSellPerBlockBreakEnabled); - boolean autoSellByPerm = isSellallEnabled && - !player.isOp() && - !"disable".equalsIgnoreCase( getMessage( AutoFeatures.permissionAutoSellPerBlockBreakEnabled ) ) && - player.hasPermission( getMessage( AutoFeatures.permissionAutoSellPerBlockBreakEnabled ) ); + + // AutoFeature's autosell per block break - global setting + boolean autoSellBySettings = + isPlayerAutosellEnabled && + isBoolean(AutoFeatures.isAutoSellPerBlockBreakEnabled); + + // AutoFeature's autosell per block break - per player perms setting + boolean autoSellByPerm = + isPlayerAutosellEnabled && + !player.isOp() && + !"disable".equalsIgnoreCase( getMessage( AutoFeatures.permissionAutoSellPerBlockBreakEnabled ) ) && + player.hasPermission( getMessage( AutoFeatures.permissionAutoSellPerBlockBreakEnabled ) ); for ( SpigotItemStack itemStack : drops ) { @@ -863,7 +874,7 @@ protected int autoPickup( PrisonMinesBlockBreakEvent pmEvent, // Try to autosell if enabled in any of the following ways: - if ( isPlayerAutosellEnabled || forceAutoSell || autoSellBySettings || autoSellByPerm ) { + if ( forceAutoSell || autoSellBySettings || autoSellByPerm ) { // // Try to autosell if enabled: // if ( isSellallEnabled && @@ -1349,6 +1360,19 @@ protected void dropExtra( HashMap extra, Player player SellAllUtil sellAllUtil = SellAllUtil.get(); + boolean isSellallEnabled = sellAllUtil != null && + SpigotPrison.getInstance().isSellAllEnabled(); + + // This will return true (allow autosell) unless players can toggle autosell and they turned it off: + // This is to be used with other auto sell setting, but never on it's own: + boolean isPlayerAutosellEnabled = + isSellallEnabled && + (!sellAllUtil.isAutoSellPerUserToggleable || + sellAllUtil.isSellallPlayerUserToggleEnabled( + player )); + + + // On inventory is full, will auto sell if auto sell is enabled in either // the sellall configs, or the auto feature configs. if (sellAllUtil != null && ( @@ -1356,7 +1380,7 @@ protected void dropExtra( HashMap extra, Player player isBoolean(AutoFeatures.isAutoSellIfInventoryIsFull) )) { - if ( sellAllUtil.checkIfPlayerAutosellIsActive(player) ) { + if ( isPlayerAutosellEnabled ) { boolean saNote = sellAllUtil.isAutoSellNotificationEnabled; diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/block/OnBlockBreakEventCore.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/block/OnBlockBreakEventCore.java index 9468458af..e5cfc9fcd 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/block/OnBlockBreakEventCore.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/block/OnBlockBreakEventCore.java @@ -868,12 +868,19 @@ else if ( results && pmEvent.getBbPriority().isMonitor() && mine != null ) { debugInfo.append( "(BLOCKEVENTS processing) " ); - // This is true if the player cannot toggle the autosell, and it's - // true if they can, and the have it enabled: - boolean isPlayerAutosellEnabled = SellAllUtil.get() != null && - SellAllUtil.get().checkIfPlayerAutosellIsActive( - pmEvent.getSpigotPlayer().getWrapper() ) - ; + SellAllUtil sellAllUtil = SellAllUtil.get(); + boolean isSellallEnabled = sellAllUtil != null && + SpigotPrison.getInstance().isSellAllEnabled(); + + // This will return true (allow autosell) unless players can toggle autosell and they turned it off: + // This is to be used with other auto sell setting, but never on it's own: + boolean isPlayerAutosellEnabled = + isSellallEnabled && + (!sellAllUtil.isAutoSellPerUserToggleable || + sellAllUtil.isSellallPlayerUserToggleEnabled( + pmEvent.getPlayer() )); + + // AutoSell on full inventory when using BLOCKEVENTS: if ( isBoolean( AutoFeatures.isAutoSellIfInventoryIsFullForBLOCKEVENTSPriority ) && diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/commands/PrisonSpigotSellAllCommands.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/commands/PrisonSpigotSellAllCommands.java index 84a79c46b..93e432064 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/commands/PrisonSpigotSellAllCommands.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/commands/PrisonSpigotSellAllCommands.java @@ -607,8 +607,9 @@ private void sellAllAutoEnableUser(CommandSender sender){ return; } - if (sellAllUtil.setAutoSellPlayer(p, !sellAllUtil.isPlayerAutoSellEnabled(p))){ - if (sellAllUtil.isPlayerAutoSellEnabled(p)){ + boolean isplayerAutosellEnabled = sellAllUtil.isPlayerAutoSellEnabled(p); + if (sellAllUtil.setAutoSellPlayer(p, !isplayerAutosellEnabled)){ + if ( !isplayerAutosellEnabled ){ // Note this variable was negated then saved, so we need to check the negative: Output.get().sendInfo(new SpigotPlayer(p), messages.getString(MessagesConfig.StringID.spigot_message_sellall_auto_enabled)); } else { Output.get().sendInfo(new SpigotPlayer(p), messages.getString(MessagesConfig.StringID.spigot_message_sellall_auto_disabled)); diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/sellall/SellAllUtil.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/sellall/SellAllUtil.java index e3108d1a4..82f3e4736 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/sellall/SellAllUtil.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/sellall/SellAllUtil.java @@ -977,6 +977,9 @@ private SellAllData sellItemStack( SpigotItemStack iStack, double multiplier ) { // } /** + * If autosell is enabled, and if user toggleable is enabled, then + * it will check to see if the player has the perm or + * * Get AutoSell Player toggle if available. * If he enabled it, AutoSell will work, otherwise it won't. * If he never used the toggle command, this will return true, just like if he enabled it in the first place. @@ -986,28 +989,77 @@ private SellAllData sellItemStack( SpigotItemStack iStack, double multiplier ) { * @return boolean. * */ public boolean isPlayerAutoSellEnabled(Player p){ + boolean results = false; + + // If autosell isn't enabled, then return false + if ( isAutoSellEnabled ) { + + results = isSellallPlayerUserToggleEnabled( p ); +// if ( !isAutoSellPerUserToggleablePermEnabled || +// isAutoSellPerUserToggleablePermEnabled && +// p.hasPermission(permissionAutoSellPerUserToggleable)){ +// +// String settingName = "Users." + p.getUniqueId() + ".isEnabled"; +// +// results = sellAllConfig.getString(settingName) == null || +// getBooleanValue( settingName ); +// } + } + + +// if (isAutoSellPerUserToggleablePermEnabled && +// !p.hasPermission(permissionAutoSellPerUserToggleable)){ +// return false; +// } +// +// if (sellAllConfig.getString("Users." + p.getUniqueId() + ".isEnabled") == null){ +// return true; +// } - if (isAutoSellPerUserToggleablePermEnabled && - !p.hasPermission(permissionAutoSellPerUserToggleable)){ - return false; - } - - if (sellAllConfig.getString("Users." + p.getUniqueId() + ".isEnabled") == null){ - return true; - } - - return getBooleanValue("Users." + p.getUniqueId() + ".isEnabled"); +// return getBooleanValue("Users." + p.getUniqueId() + ".isEnabled"); + return results; } - public boolean checkIfPlayerAutosellIsActive(Player p) { - boolean results = true; + /** + *

This function only checks to see if the user can toggle autosell + * on or off. If they can, then it checks the state to see if it's on + * or off. It does not matter if autosell is enabled within sellall or not, + * since this can be used with the auto features autosell too. + *

+ * + * + * + * @param p + * @return + */ + public boolean isSellallPlayerUserToggleEnabled( Player p ) { + boolean results = false; - if ( isAutoSellPerUserToggleable ) { - results = isPlayerAutoSellEnabled(p); + if ( isAutoSellPerUserToggleable ) { + + if ( !isAutoSellPerUserToggleablePermEnabled || + isAutoSellPerUserToggleablePermEnabled && + p.hasPermission(permissionAutoSellPerUserToggleable)){ + + String settingName = "Users." + p.getUniqueId() + ".isEnabled"; + + results = sellAllConfig.getString( settingName ) == null || + getBooleanValue( settingName ); + } } return results; } + +// public boolean checkIfPlayerAutosellIsActive(Player p) { +// boolean results = isAutoSellEnabled; +// +// if ( isAutoSellPerUserToggleable ) { +// results = isPlayerAutoSellEnabled(p); +// } +// +// return results; +// } // /** // * WARNING: Obsolete because disabled worlds are set in config.yml and From 0ef001100512c78b834ade4f5419b4b703dcfa0d Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sun, 30 Jul 2023 00:22:38 -0400 Subject: [PATCH 053/151] Sellall: Rearrange the sellall commands so they are better organized and updated the help text so its also meaningful. --- docs/changelog_v3.3.x.md | 3 + .../spigot/block/OnBlockBreakEventCore.java | 1 - .../commands/PrisonSpigotSellAllCommands.java | 80 ++++++++++++------- 3 files changed, 54 insertions(+), 30 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 9c60f0c5b..e7271a607 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -17,6 +17,9 @@ These change logs represent the work that has been going on within prison. # 3.3.0-alpha.15b 2023-07-29 +* **Sellall: Rearrange the sellall commands so they are better organized and updated the help text so its also meaningful.** + + * **sellall & autosell: auto sell was not working correctly within auto manager.** Also fixed the user toggle on auto sell so players can turn off autosell when they need to. diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/block/OnBlockBreakEventCore.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/block/OnBlockBreakEventCore.java index e5cfc9fcd..3a0e7736c 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/block/OnBlockBreakEventCore.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/block/OnBlockBreakEventCore.java @@ -884,7 +884,6 @@ else if ( results && pmEvent.getBbPriority().isMonitor() && mine != null ) { // AutoSell on full inventory when using BLOCKEVENTS: if ( isBoolean( AutoFeatures.isAutoSellIfInventoryIsFullForBLOCKEVENTSPriority ) && - SpigotPrison.getInstance().isSellAllEnabled() && isPlayerAutosellEnabled && pmEvent.getSpigotPlayer().isInventoryFull() ) { diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/commands/PrisonSpigotSellAllCommands.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/commands/PrisonSpigotSellAllCommands.java index 93e432064..b69306ae9 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/commands/PrisonSpigotSellAllCommands.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/commands/PrisonSpigotSellAllCommands.java @@ -103,10 +103,13 @@ private void sellAllCommands(CommandSender sender) { } } - @Command(identifier = "sellall delay", description = "SellAll delay.", + @Command(identifier = "sellall set delay", + description = "Enables or disables a SellAll cooldown delay to preventh " + + "players from spamming the sellall command. " + + "See `/sellall set delayTime`.", onlyPlayers = false, permissions = "prison.sellall.delay") private void sellAllDelay(CommandSender sender, - @Arg(name = "boolean", description = "True to enable or false to disable.", def = "null") String enable){ + @Arg(name = "boolean", description = "True to enable or false to disable.", def = "false") String enable){ if (!isEnabled()) return; @@ -140,10 +143,12 @@ private void sellAllDelay(CommandSender sender, } } - @Command(identifier = "sellall set delay", description = "Edit SellAll delay.", + @Command(identifier = "sellall set delayTime", + description = "This sets the sellall cooldown delay to the specified number of seconds.", onlyPlayers = false, permissions = "prison.sellall.delay") private void sellAllDelaySet(CommandSender sender, - @Arg(name = "delay", description = "Set delay value in seconds.", def = "0") String delay){ + @Arg(name = "delay", + description = "Set delay value in seconds. Defaults to a value of 15 seconds.", def = "15") String delay){ if (!isEnabled()) return; @@ -165,7 +170,7 @@ private void sellAllDelaySet(CommandSender sender, } } - @Command(identifier = "sellall autosell", + @Command(identifier = "sellall set autosell", description = "Enable SellAll AutoSell. " + "For AutoFeatures based sellall, please see the AutoFeatures configs.", onlyPlayers = false, permissions = "prison.autosell.edit") @@ -212,12 +217,13 @@ private void sellAllAutoSell(CommandSender sender, } } - @Command(identifier = "sellall autosell perUserToggleable", + @Command(identifier = "sellall set autosellPerUserToggleable", description = "Enable AutoSell perUserToggleable. This will " + "enable autosell if it's not already enabled, plus it will allow players to " - + "turn autosell on/off when they need to using the command `/sellall auto toggle`. " + + "turn autosell on/off when they need to using the " + + "command `/sellall autoSellToggle` or the alias `/autosell`. " + "If user toggleable is disabled through this command, it will also disable " - + "autosell, so you may need to turn it back on with `/sellall autosell true`.", + + "autosell, so you may need to turn it back on with `/sellall set autosell true`.", onlyPlayers = false, permissions = "prison.autosell.edit") private void sellAllAutoSellPerUserToggleable(CommandSender sender, @Arg(name = "boolean", @@ -330,7 +336,8 @@ else if (p == null){ PlayerAutoRankupTask.autoSubmitPlayerRankupTask( sPlayer, null ); } - @Command(identifier = "sellall hand", description = "Sell only what is in your hand if sellable.", + @Command(identifier = "sellall sellHand", + description = "Sell only what is in your hand if it is sellable.", onlyPlayers = true) public void sellAllSellHandCommand(CommandSender sender){ @@ -408,8 +415,8 @@ public void sellAllSell(Player p){ - @Command(identifier = "sellall valueof", - description = "SellAll valueof command will report the total value of the player's inventory " + @Command(identifier = "sellall valueOf", + description = "SellAll valueOf command will report the total value of the player's inventory " + "without selling anything.", onlyPlayers = false) public void sellAllValueOfCommand(CommandSender sender, @Arg(name = "player", def = "", description = "An online player name to get the value of their inventory - " + @@ -448,7 +455,7 @@ else if (p == null){ if ( getPlayer( sender, playerName ) != null ) { Output.get().sendInfo(sender, "&cSorry but the specified player must be online " - + "[/sellall valueof %s]", playerName ); + + "[/sellall valueOf %s]", playerName ); } else { @@ -485,7 +492,7 @@ else if (p == null){ PlayerAutoRankupTask.autoSubmitPlayerRankupTask( sPlayer, null ); } - @Command(identifier = "sellall valueofHand", + @Command(identifier = "sellall valueOfHand", description = "Get the value of what is in your hand if sellable.", onlyPlayers = true) public void sellAllValueOfHandCommand(CommandSender sender){ @@ -499,7 +506,7 @@ public void sellAllValueOfHandCommand(CommandSender sender){ } if (!sellAllUtil.isSellAllHandEnabled){ - Output.get().sendWarn(sender, "The command /sellall valueofHand is disabled from the config! (SellAllHandEnabled)"); + Output.get().sendWarn(sender, "The command `/sellall valueOfHand` is disabled from the config! (SellAllHandEnabled)"); return; } @@ -573,10 +580,12 @@ public void sellAllSellWithDelayCommand(CommandSender sender){ } - @Command(identifier = "sellall auto toggle", + @Command(identifier = "sellall autoSellToggle", + aliases = {"autosell"}, description = "When `perUserToggleable` is enabled with autosell, this " + "command allow the players to enable or disable their own use of autosell. " - + "When using this command, autosell will be toggled on/off for the player.", + + "When using this command, autosell will be toggled on/off for the player. " + + "Can also use the alias `/autosell` to toggle this setting", altPermissions = "prison.sellall.toggle", onlyPlayers = true) private void sellAllAutoEnableUser(CommandSender sender){ @@ -676,11 +685,16 @@ private void sellAllGuiBlocksCommand(CommandSender sender, } - @Command(identifier = "sellall add", description = "SellAll add an item to the sellAll shop.", + @Command(identifier = "sellall items add", + description = "This will add an item to the SellAll shop. " + + "Use `/mines block search help` to find the correct names " + + "for blocks to add to the sellall shop. Use " + + "`/mines block searchAll help` to search for items too.", permissions = "prison.admin", onlyPlayers = false) private void sellAllAddCommand(CommandSender sender, - @Arg(name = "Item_ID", description = "The Item_ID or block to add to the sellAll Shop.") String itemID, - @Arg(name = "Value", description = "The value of the item.") Double value){ + @Arg(name = "Item_ID", + description = "The Item_ID or block to add to the sellAll Shop.") String itemID, + @Arg(name = "Value", description = "The value of the item.") Double value){ if (!isEnabled()) return; @@ -750,9 +764,12 @@ public void sellAllAddCommand(XMaterial blockAdd, Double value){ Output.get().logInfo("&3 ITEM [" + itemID + ", " + value + " " + messages.getString(MessagesConfig.StringID.spigot_message_sellall_item_add_success)); } - @Command(identifier = "sellall delete", description = "SellAll delete command, remove an item from shop.", + @Command(identifier = "sellall items delete", + description = "This command will delete an item from the " + + "sellall shop. Use `/sellall list` to identify which items to revmove.", permissions = "prison.admin", onlyPlayers = false) - private void sellAllDeleteCommand(CommandSender sender, @Arg(name = "Item_ID", description = "The Item_ID you want to remove.") String itemID){ + private void sellAllDeleteCommand(CommandSender sender, + @Arg(name = "Item_ID", description = "The Item_ID you want to remove.") String itemID){ if (!isEnabled()) return; @@ -779,11 +796,12 @@ private void sellAllDeleteCommand(CommandSender sender, @Arg(name = "Item_ID", d } } - @Command(identifier = "sellall edit", description = "SellAll edit command, edit an item of Shop.", + @Command(identifier = "sellall items edit", + description = "Edits an existing SellAll shop item.", permissions = "prison.admin", onlyPlayers = false) private void sellAllEditCommand(CommandSender sender, - @Arg(name = "Item_ID", description = "The Item_ID or block to add to the sellAll Shop.") String itemID, - @Arg(name = "Value", description = "The value of the item.") Double value){ + @Arg(name = "Item_ID", description = "The Item_ID or block to add to the sellAll Shop.") String itemID, + @Arg(name = "Value", description = "The value of the item.") Double value){ if (!isEnabled()) return; @@ -987,12 +1005,14 @@ private void sellAllDeleteMultiplierCommand(CommandSender sender, } } - @Command(identifier = "sellall trigger", - description = "Toggle SellAll Shift+Right Click on a tool to trigger the /sellall sell command, " - + "true -> Enabled or False -> Disabled.", + @Command(identifier = "sellall set trigger", + description = "Toggle SellAll trigger to enable/disable the Shift+Right Clicking " + + "on a tool to trigger the `/sellall sell` command " + + "true = enable, false = disable. " + + "[true false].", permissions = "prison.admin", onlyPlayers = false) private void sellAllToolsTriggerToggle(CommandSender sender, - @Arg(name = "Boolean", description = "Enable or disable", def = "null") String enable){ + @Arg(name = "Boolean", description = "Enable or disable", def = "true") String enable){ if (!isEnabled()) return; @@ -1113,7 +1133,9 @@ private void sellAllTriggerDelete(CommandSender sender, } } - @Command(identifier = "sellall setdefault", description = "SellAll default values ready to go.", + @Command(identifier = "sellall items setdefaults", + description = "This command will setup all of the shop items with " + + "the SellAll default items.", permissions = "prison.admin", onlyPlayers = false) private void sellAllSetDefaultCommand(CommandSender sender){ From 401820e8e4e2b5d9f82ae80b89e8730ca02007db Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sun, 30 Jul 2023 22:59:44 -0400 Subject: [PATCH 054/151] ranks autoConfigure: Major enhancements to add more prestige ranks. More options have been added: prestiges prestiges=x prestigesCost=x prestigesMult=x. Now able to add more prestige ranks without impacting ranks or mines. Example to add up to 50 new prestige ranks: `/ranks autoConfigure force presetiges prestiges=50` --- docs/changelog_v3.3.x.md | 9 +- .../prison/ranks/commands/RanksCommands.java | 120 +++++++++++++++--- 2 files changed, 112 insertions(+), 17 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index e7271a607..a79d62916 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -14,7 +14,14 @@ These change logs represent the work that has been going on within prison. -# 3.3.0-alpha.15b 2023-07-29 +# 3.3.0-alpha.15b 2023-07-30 + + +* **ranks autoConfigure: Major enhancements to add more prestige ranks.** +Added a lot more informatio to the command's help: `/ranks autoConfigure help`. +More options have been added: prestiges prestiges=x prestigesCost=x prestigesMult=x. +Now able to add more prestige ranks without impacting ranks or mines. +Example to add up to 50 new prestige ranks: `/ranks autoConfigure force presetiges prestiges=50` * **Sellall: Rearrange the sellall commands so they are better organized and updated the help text so its also meaningful.** diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/RanksCommands.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/RanksCommands.java index d1fae5859..df269b9a5 100644 --- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/RanksCommands.java +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/RanksCommands.java @@ -216,20 +216,43 @@ public boolean createRank(CommandSender sender, } - @Command(identifier = "ranks autoConfigure", description = "Auto configures Ranks and Mines using " + + @Command(identifier = "ranks autoConfigure", + description = "Auto configures Ranks, Mines, and Prestiges using " + "single letters A through Z for both the rank and mine names. Both ranks and mines are " + "generated, they will also be linked together automatically. To set the starting price use " + - "price=x. To set multiplier mult=x. AutoConfigure will try to merge any preexsiting ranks " + - "and mines, but you must use the 'force' keyword in 'options'. Force will replace all blocks " + - "in preexisting " + + "'price=x'. To set multiplier 'mult=x'. AutoConfigure will try to merge any preexsiting ranks " + + "and mines, but you must use the 'force' keyword in 'options' and force will " + + "replace all blocks in preexisting " + "mines. To keep preexisting blocks, use 'forceKeepBlocks' with the 'force' option. " + - "Default values [full price=50000 mult=1.5]", + + "The option 'full' will enable ranks, mines, and prestiges. No options will default to 'full'. " + + "The options 'ranks', 'mines', and 'prestiges' will enable each of these if they are listed. " + + "So using just 'mines' will only generate mines and no ranks or prestiges." + + + "The option 'prestiges=x' will set how many initial prestige ranks to create. " + + "The option `prestigeCost=x` sets the intial cost for P1; default value is 1_000_000_000. " + + "The option 'prestigeMult=x' is an additional multiplier for presetige ranks, with the " + + "default value of 1. The cost for each prestige rank is based upon the initial " + + "presetigeCost, times the prestige level so p3 will be 3 times the cost of p1 with the " + + "prestige multiplier will multipled against that value. So for default values " + + " with a 1.75 multipler p3 cost = 1_000_000_000 * 3 * 1.75. " + + "Default values [full price=50000 mult=1.5 prestiges=25 presetigeCost=1000000000 " + + "prestigeMult=1] " + + + "Example of just adding more prestige ranks using the other default values: " + + "'/ranks autoConfigure force prestiges presetiges=1000', no ranks and no mines will " + + "be created. " + + "Warning: If trying to rerun autoConfigure with existing mines or ranks, then do a " + + "prison backup with this command: '/prison support backup save adding more prestiges'", onlyPlayers = false, permissions = "ranks.set", aliases = {"prison autoConfigure"} ) public void autoConfigureRanks(CommandSender sender, @Wildcard(join=true) @Arg(name = "options", - description = "Options: [full ranks mines price=x mult=x force forceKeepBlocks dontForceLinerWalls dontForceLinerBottoms]", + description = "Options: [full ranks mines prestiges price=x mult=x " + + "prestiges=x prestigeCost=x prestigeMult=x " + + "force forceKeepBlocks " + + "dontForceLinerWalls dontForceLinerBottoms]", def = "full") String options ) { @@ -240,6 +263,9 @@ public void autoConfigureRanks(CommandSender sender, boolean forceLinersWalls = true; boolean forceLinersBottom = true; boolean forceKeepBlocks = false; + int prestigeRanks = 25; + long prestigeCost = 1_000_000_000; + double prestigeMult = 10d; if ( options.contains( "forcekeepblocks" ) ) { @@ -274,9 +300,13 @@ public void autoConfigureRanks(CommandSender sender, autoConfigForceWarningMsg( sender ); } - String optionHelp = "&b[&7full ranks mines price=&dx &7mult=&dx &7force forceKeepBlocks dontForceLinerWalls dontForceLinerBottoms&b]"; + String optionHelp = "&b[&7full ranks mines prestiges price=&dx &7mult=&dx " + + "&7prestiges=&dx &7prestigeCost=&dx &7prestigeMult=&dx " + + "&7force forceKeepBlocks dontForceLinerWalls dontForceLinerBottoms&b]"; boolean ranks = false; boolean mines = false; + boolean prestiges = false; + double startingPrice = 50000; double percentMultipler = 1.5; @@ -292,6 +322,7 @@ public void autoConfigureRanks(CommandSender sender, if ( options.contains( "full" ) ) { ranks = true; mines = true; + prestiges = true; options = options.replace( "full", "" ).trim(); } if ( options.contains( "ranks" ) ) { @@ -302,6 +333,7 @@ public void autoConfigureRanks(CommandSender sender, mines = true; options = options.replace( "mines", "" ).trim(); } + String priceStr = extractParameter("price=", options); if ( priceStr != null ) { @@ -329,6 +361,53 @@ public void autoConfigureRanks(CommandSender sender, // Not a valid double number, or price: } } + + String prestigesStr = extractParameter("prestiges=", options); + if ( prestigesStr != null ) { + options = options.replace( prestigesStr, "" ); + prestigesStr = prestigesStr.replace( "prestiges=", "" ).trim(); + + try { + prestigeRanks = Integer.parseInt( prestigesStr ); + } + catch ( NumberFormatException e ) { + // Not a valid double number, or price: + } + } + + String prestigeCostStr = extractParameter("prestigeCost=", options); + if ( prestigeCostStr != null ) { + options = options.replace( prestigeCostStr, "" ); + prestigeCostStr = prestigeCostStr.replace( "prestigeCost=", "" ).trim(); + + try { + prestigeCost = Long.parseLong( prestigeCostStr ); + } + catch ( NumberFormatException e ) { + // Not a valid double number, or price: + } + } + + String prestigeMultStr = extractParameter("prestigeMult=", options); + if ( prestigeMultStr != null ) { + options = options.replace( prestigeMultStr, "" ); + prestigeMultStr = prestigeMultStr.replace( "prestigeMult=", "" ).trim(); + + try { + prestigeMult = Double.parseDouble( prestigeMultStr ); + } + catch ( NumberFormatException e ) { + // Not a valid double number, or price: + } + } + + // This has to be checked after prestiges= or this will destroy that config setting: + if ( options.contains( "prestiges" ) ) { + prestiges = true; + options = options.replace( "prestiges", "" ).trim(); + } + + // What's left over, if not just a blank string, must be an error: @@ -491,13 +570,22 @@ public void autoConfigureRanks(CommandSender sender, int prestigesCount = 0; // add in 10 prestiges at 1 billion each: - double prestigeCost = 1000000000; +// double prestigeCost = 1_000_000_000; - for ( int i = 0; i < 10; i++ ) { - String name = "P" + (i + 1); - String tag = "&5[&d+" + (i > 0 ? i + 1 : "" ) + "&5]"; - createRank(sender, name, (prestigeCost * (i + 1) ), LadderManager.LADDER_PRESTIGES, tag, "noPlaceholderUpdate"); - prestigesCount++; + if ( prestiges ) { + + for ( int i = 0; i < prestigeRanks; i++ ) { + String name = "P" + (i + 1); + String tag = "&5[&d+" + (i > 0 ? i + 1 : "" ) + "&5]"; + double cost = prestigeCost * (i + 1) * prestigeMult; + + // Only add prestige ranks if they do not already exist: + if ( PrisonRanks.getInstance().getRankManager().getRank( name ) == null ) { + + createRank(sender, name, cost, LadderManager.LADDER_PRESTIGES, tag, "noPlaceholderUpdate"); + prestigesCount++; + } + } } // If mines were created, go ahead and auto assign blocks to the mines: @@ -517,9 +605,9 @@ public void autoConfigureRanks(CommandSender sender, // Set the prestiges ladder with a 10% base rank cost multiplier double rankCostMultiplier = 0.10; - RankLadder prestiges = PrisonRanks.getInstance().getLadderManager().getLadder( LadderManager.LADDER_PRESTIGES ); - prestiges.setRankCostMultiplierPerRank( rankCostMultiplier ); - PrisonRanks.getInstance().getLadderManager().save( prestiges ); + RankLadder prestigesLadder = PrisonRanks.getInstance().getLadderManager().getLadderPrestiges(); + prestigesLadder.setRankCostMultiplierPerRank( rankCostMultiplier ); + PrisonRanks.getInstance().getLadderManager().save( prestigesLadder ); // Log that the rank cost multiplier has been applied to the ladder // with information on how to change it. From 742afe6729d98482074cf901db6b24b7efc8a404 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sun, 30 Jul 2023 23:03:58 -0400 Subject: [PATCH 055/151] RevEnchants: added additional logging and details if there is a failure trying to hook into the RevEnchant's events. Trying to see if there is additional causedBy information. --- docs/changelog_v3.3.x.md | 4 ++++ .../events/AutoManagerRevEnchantsExplosiveEvent.java | 7 ++++++- .../events/AutoManagerRevEnchantsJackHammerEvent.java | 7 ++++++- .../tech/mcprison/prison/spigot/sellall/SellAllUtil.java | 3 ++- 4 files changed, 18 insertions(+), 3 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index a79d62916..793ce3c35 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -17,6 +17,10 @@ These change logs represent the work that has been going on within prison. # 3.3.0-alpha.15b 2023-07-30 +* **RevEnchants: added additional logging and details if there is a failure trying to hook into the RevEnchant's events.** +Trying to see if there is additional causedBy information. + + * **ranks autoConfigure: Major enhancements to add more prestige ranks.** Added a lot more informatio to the command's help: `/ranks autoConfigure help`. More options have been added: prestiges prestiges=x prestigesCost=x prestigesMult=x. diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerRevEnchantsExplosiveEvent.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerRevEnchantsExplosiveEvent.java index 32b49b5d0..c04881870 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerRevEnchantsExplosiveEvent.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerRevEnchantsExplosiveEvent.java @@ -241,7 +241,12 @@ public void dumpEventListeners( StringBuilder sb ) { // CrazyEnchants is not loaded... so ignore. } catch ( Exception e ) { - Output.get().logInfo( "AutoManager: RevEnchants ExplosiveEvent failed to load. [%s]", e.getMessage() ); + String causedBy = e.getCause() == null ? "" : e.getCause().getMessage(); + + Output.get().logInfo( "AutoManager: RevEnchants ExplosiveEvent failed to load. " + + "[%s] Caused by: [%s]", + e.getMessage(), + causedBy ); } } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerRevEnchantsJackHammerEvent.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerRevEnchantsJackHammerEvent.java index 8f29c41d1..8aac7fa3c 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerRevEnchantsJackHammerEvent.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerRevEnchantsJackHammerEvent.java @@ -249,7 +249,12 @@ public void dumpEventListeners( StringBuilder sb ) { // CrazyEnchants is not loaded... so ignore. } catch ( Exception e ) { - Output.get().logInfo( "AutoManager: RevEnchants JackHammerEnchants failed to load. [%s]", e.getMessage() ); + String causedBy = e.getCause() == null ? "" : e.getCause().getMessage(); + + Output.get().logInfo( "AutoManager: RevEnchants JackHammerEnchants failed to load. " + + "[%s] Caused by: [%s]", + e.getMessage(), + causedBy, e.getMessage() ); } } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/sellall/SellAllUtil.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/sellall/SellAllUtil.java index 82f3e4736..8927c8b30 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/sellall/SellAllUtil.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/sellall/SellAllUtil.java @@ -1438,7 +1438,8 @@ public boolean addItemTrigger(XMaterial xMaterial){ public void addToDelay(Player p){ if (!isPlayerWaitingSellAllDelay(p)){ activePlayerDelay.add(p); - Bukkit.getScheduler().scheduleSyncDelayedTask(SpigotPrison.getInstance(), () -> removeFromDelay(p), 20L * defaultSellAllDelay); + Bukkit.getScheduler().scheduleSyncDelayedTask( + SpigotPrison.getInstance(), () -> removeFromDelay(p), 20L * defaultSellAllDelay); } } From 74aef9a551924657b667faceb37e1e235a24e94f Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sun, 30 Jul 2023 23:06:48 -0400 Subject: [PATCH 056/151] v3.3.0-alpha.15c 2023-07-30 --- docs/changelog_v3.3.x.md | 5 ++++- gradle.properties | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 793ce3c35..fc56ee8fe 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -14,7 +14,10 @@ These change logs represent the work that has been going on within prison. -# 3.3.0-alpha.15b 2023-07-30 +# 3.3.0-alpha.15c 2023-07-30 + + +**v3.3.0-alpha.15c 2023-07-30** * **RevEnchants: added additional logging and details if there is a failure trying to hook into the RevEnchant's events.** diff --git a/gradle.properties b/gradle.properties index 9aa660bdb..3bf67908a 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,7 +3,7 @@ ## # This is actually the "correct" place to define the version for the project. ## # Used within build.gradle with ${project.version}. ## # Can be overridden on the command line: gradle -Pversion=3.2.1-alpha.3 -version=3.3.0-alpha.15b +version=3.3.0-alpha.15c From 4339fd4e6f34d7d67a6b7f70a03c8765f35a8aef Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Fri, 4 Aug 2023 10:00:30 -0400 Subject: [PATCH 057/151] AutoFeatures: Add support for the XPrison enchantments. Please be aware that event priorities must be adjusted. You can change prison's event priorities, but XPrison is hard coded to NORMAL So to get this work, you may have to adjust prison's priorities so it is after XPrison's. We cannot support XPrison especially if their event priorities become a problem, or causes a problem. --- docs/changelog_v3.3.x.md | 7 ++++- .../autofeatures/AutoFeaturesFileConfig.java | 4 +++ .../prison/mines/features/MineBlockEvent.java | 11 ++++++- .../prison/spigot/SpigotPlatform.java | 17 +++++++++++ .../block/OnBlockBreakEventListener.java | 30 ++++++++++++++++++- 5 files changed, 66 insertions(+), 3 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index fc56ee8fe..00101085d 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -14,7 +14,12 @@ These change logs represent the work that has been going on within prison. -# 3.3.0-alpha.15c 2023-07-30 +# 3.3.0-alpha.15c 2023-08-04 + + +* **AutoFeatures: Add support for the XPrison enchantments.** +Please be aware that event priorities must be adjusted. You can change prison's event priorities, but XPrison is hard coded to NORMAL So to get this work, you may have to adjust prison's priorities so it is after XPrison's. +We cannot support XPrison especially if their event priorities become a problem, or causes a problem. **v3.3.0-alpha.15c 2023-07-30** diff --git a/prison-core/src/main/java/tech/mcprison/prison/autofeatures/AutoFeaturesFileConfig.java b/prison-core/src/main/java/tech/mcprison/prison/autofeatures/AutoFeaturesFileConfig.java index b2498aff3..b8d92591d 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/autofeatures/AutoFeaturesFileConfig.java +++ b/prison-core/src/main/java/tech/mcprison/prison/autofeatures/AutoFeaturesFileConfig.java @@ -127,6 +127,10 @@ public enum AutoFeatures { PrisonEnchantsExplosiveEventPriority(blockBreakEvents, "DISABLED"), + XPrisonExplosionTriggerEventPriority(blockBreakEvents, "DISABLED"), + XPrisonLayerTriggerEventPriority(blockBreakEvents, "DISABLED"), + XPrisonNukeTriggerEventPriority(blockBreakEvents, "DISABLED"), + blockBreakEvents__ReadMe(blockBreakEvents, "Use the following event priorities with the blockBreakEvents: " + diff --git a/prison-mines/src/main/java/tech/mcprison/prison/mines/features/MineBlockEvent.java b/prison-mines/src/main/java/tech/mcprison/prison/mines/features/MineBlockEvent.java index 7873665d8..c34a3d527 100644 --- a/prison-mines/src/main/java/tech/mcprison/prison/mines/features/MineBlockEvent.java +++ b/prison-mines/src/main/java/tech/mcprison/prison/mines/features/MineBlockEvent.java @@ -41,12 +41,21 @@ public enum BlockEventType { RevEnExplosion, RevEnJackHammer, + ExplosionTriggerEvent, + LayerTriggerEvent, + NukeTriggerEvent, + eventTypeAll( all ), eventBlockBreak( blockBreak ), eventTEXplosion( TEXplosion ), eventRevEnExplosion( RevEnExplosion ), - eventRevEnJackHammer( RevEnJackHammer ), + eventRevEnJackHammer( RevEnJackHammer ), + + XPrisonExplosionTriggerEvent( ExplosionTriggerEvent ), + XPrisonLayerTriggerEvent( LayerTriggerEvent ), + XPrisonNukeTriggerEvent( NukeTriggerEvent ), + ; diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/SpigotPlatform.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/SpigotPlatform.java index 13603d703..31ffd82cb 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/SpigotPlatform.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/SpigotPlatform.java @@ -115,6 +115,9 @@ import tech.mcprison.prison.spigot.autofeatures.events.AutoManagerRevEnchantsExplosiveEvent; import tech.mcprison.prison.spigot.autofeatures.events.AutoManagerRevEnchantsJackHammerEvent; import tech.mcprison.prison.spigot.autofeatures.events.AutoManagerTokenEnchant; +import tech.mcprison.prison.spigot.autofeatures.events.AutoManagerXPrisonExplosionTriggerEvent; +import tech.mcprison.prison.spigot.autofeatures.events.AutoManagerXPrisonLayerTriggerEvent; +import tech.mcprison.prison.spigot.autofeatures.events.AutoManagerXPrisonNukeTriggerEvent; import tech.mcprison.prison.spigot.autofeatures.events.AutoManagerZenchantments; import tech.mcprison.prison.spigot.backpacks.BackpacksUtil; import tech.mcprison.prison.spigot.block.BlockBreakPriority; @@ -2660,6 +2663,20 @@ public String dumpEventListenersBlockBreakEvents() { zenchantments.dumpEventListeners( sb ); + + AutoManagerXPrisonExplosionTriggerEvent xpExplosion = new AutoManagerXPrisonExplosionTriggerEvent(); + xpExplosion.dumpEventListeners( sb ); + + AutoManagerXPrisonLayerTriggerEvent xpLayer = new AutoManagerXPrisonLayerTriggerEvent(); + xpLayer.dumpEventListeners( sb ); + + AutoManagerXPrisonNukeTriggerEvent xpNuke = new AutoManagerXPrisonNukeTriggerEvent(); + xpNuke.dumpEventListeners( sb ); + + + + + // Shorten the prison package names: // 'tmps.' = 'tech.mcprison.prison.spigot.' // 'tmpsae.' = 'tmps.autofeatures.events.' diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/block/OnBlockBreakEventListener.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/block/OnBlockBreakEventListener.java index a604f1b8a..f693a3c41 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/block/OnBlockBreakEventListener.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/block/OnBlockBreakEventListener.java @@ -17,6 +17,9 @@ import tech.mcprison.prison.spigot.autofeatures.events.AutoManagerRevEnchantsExplosiveEvent; import tech.mcprison.prison.spigot.autofeatures.events.AutoManagerRevEnchantsJackHammerEvent; import tech.mcprison.prison.spigot.autofeatures.events.AutoManagerTokenEnchant; +import tech.mcprison.prison.spigot.autofeatures.events.AutoManagerXPrisonExplosionTriggerEvent; +import tech.mcprison.prison.spigot.autofeatures.events.AutoManagerXPrisonLayerTriggerEvent; +import tech.mcprison.prison.spigot.autofeatures.events.AutoManagerXPrisonNukeTriggerEvent; import tech.mcprison.prison.spigot.autofeatures.events.AutoManagerZenchantments; import tech.mcprison.prison.spigot.autofeatures.events.PrisonDebugBlockInspector; @@ -111,10 +114,16 @@ public class OnBlockBreakEventListener private AutoManagerRevEnchantsExplosiveEvent reEEvents; private AutoManagerRevEnchantsJackHammerEvent reJHEvents; - + private AutoManagerXPrisonExplosionTriggerEvent xpExpEvents; + private AutoManagerXPrisonLayerTriggerEvent xpLayerEvents; + private AutoManagerXPrisonNukeTriggerEvent xpNukeEvents; + + private PrisonDebugBlockInspector pdBlockInspector; + + public OnBlockBreakEventListener() { super(); @@ -227,6 +236,15 @@ private void registerEvents() { reJHEvents = new AutoManagerRevEnchantsJackHammerEvent(); + + xpExpEvents = new AutoManagerXPrisonExplosionTriggerEvent(); + + xpLayerEvents = new AutoManagerXPrisonLayerTriggerEvent(); + + xpNukeEvents = new AutoManagerXPrisonNukeTriggerEvent(); + + + if ( AutoFeaturesWrapper.getInstance().isBoolean(AutoFeatures.isAutoManagerEnabled) ) { bbEvents.registerEvents(); @@ -245,9 +263,19 @@ private void registerEvents() { reEEvents.registerEvents(); reJHEvents.registerEvents(); + + + xpExpEvents.registerEvents(); + + xpLayerEvents.registerEvents(); + + xpNukeEvents.registerEvents(); + } pdBlockInspector = PrisonDebugBlockInspector.getInstance(); + pdBlockInspector.getClass(); + // pdBlockInspector.init(); } From 7d74600fcab0b72eca1296ccd6bd01731db96526 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Fri, 4 Aug 2023 10:01:50 -0400 Subject: [PATCH 058/151] Fixed the formatting... since this is a demo test app, it cannot use the global prison decimal formatting since it's not being loaded. --- .../mcprison/prison/util/ExampleJavaDoubleVsBigDecimal.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/prison-core/src/main/java/tech/mcprison/prison/util/ExampleJavaDoubleVsBigDecimal.java b/prison-core/src/main/java/tech/mcprison/prison/util/ExampleJavaDoubleVsBigDecimal.java index a856abc35..5f59bfc4e 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/util/ExampleJavaDoubleVsBigDecimal.java +++ b/prison-core/src/main/java/tech/mcprison/prison/util/ExampleJavaDoubleVsBigDecimal.java @@ -4,8 +4,6 @@ import java.text.DecimalFormat; import java.util.ArrayList; -import tech.mcprison.prison.Prison; - public class ExampleJavaDoubleVsBigDecimal { public static void main( String[] args ) { @@ -36,7 +34,7 @@ private ArrayList runSample() { StringBuilder sb = new StringBuilder(); sb.append( ".111111" ); - DecimalFormat dFmt = Prison.get().getDecimalFormat( "#,##0.00000" ); + DecimalFormat dFmt = new DecimalFormat( "#,##0.00000" ); for ( int i = 1; i < 25; i++ ) { sb.insert( 0, "1" ); From c141735c268026a57be87bd04baec9fd17dc9a8a Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Fri, 4 Aug 2023 10:04:17 -0400 Subject: [PATCH 059/151] AutoFeatures BlockInspector: Fixed a bug with not negating a condition... was causing some problems since it was misreporting the results. --- docs/changelog_v3.3.x.md | 4 ++++ .../spigot/autofeatures/events/PrisonDebugBlockInspector.java | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 00101085d..00576b4e0 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -17,6 +17,10 @@ These change logs represent the work that has been going on within prison. # 3.3.0-alpha.15c 2023-08-04 + +* ** AutoFeatures BlockInspector: Fixed a bug with not negating a condition... was causing some problems since it was misreporting the results.** + + * **AutoFeatures: Add support for the XPrison enchantments.** Please be aware that event priorities must be adjusted. You can change prison's event priorities, but XPrison is hard coded to NORMAL So to get this work, you may have to adjust prison's priorities so it is after XPrison's. We cannot support XPrison especially if their event priorities become a problem, or causes a problem. diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/PrisonDebugBlockInspector.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/PrisonDebugBlockInspector.java index a0db0925a..77a531c71 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/PrisonDebugBlockInspector.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/PrisonDebugBlockInspector.java @@ -525,7 +525,7 @@ private EventDropsStatus isDropCanceled( BlockBreakEvent bbe ) { EventDropsStatus results = EventDropsStatus.normal; try { - if ( bbe.isDropItems() ) { + if ( !bbe.isDropItems() ) { results = EventDropsStatus.canceled; } else { From 22f521c5231052ef6a11262a5cd595ef7f90814d Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Fri, 4 Aug 2023 10:06:36 -0400 Subject: [PATCH 060/151] Prestiges: Bug fix. If no prestige rank, then prevent a NPE. Totally thought this was fixed a while ago? --- docs/changelog_v3.3.x.md | 5 ++++- .../tech/mcprison/prison/ranks/commands/RankUpCommand.java | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 00576b4e0..f46f58547 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -17,8 +17,11 @@ These change logs represent the work that has been going on within prison. # 3.3.0-alpha.15c 2023-08-04 +* **Prestiges: Bug fix. If no prestige rank, then prevent a NPE on a simple check.** +Totally thought this was fixed a while ago? -* ** AutoFeatures BlockInspector: Fixed a bug with not negating a condition... was causing some problems since it was misreporting the results.** + +* **AutoFeatures BlockInspector: Fixed a bug with not negating a condition... was causing some problems since it was misreporting the results.** * **AutoFeatures: Add support for the XPrison enchantments.** diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/RankUpCommand.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/RankUpCommand.java index d7bb62685..6ca277370 100644 --- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/RankUpCommand.java +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/RankUpCommand.java @@ -458,7 +458,10 @@ private boolean rankUpPrivate(CommandSender sender, String playerName, String la PlayerRank rankCurrent = rankPlayer.getPlayerRank(ladder); - if ( rankCurrent.getRank().getRankNext() == null ) { + + + // If the player has a rank on the target ladder, mmake sure the next rank is not null + if ( rankCurrent != null && rankCurrent.getRank().getRankNext() == null ) { rankupAtLastRankMsg(sender); return false; } From 3d3195f7bc82d98e80f72320a8f6e7415869e4eb Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Fri, 4 Aug 2023 10:33:44 -0400 Subject: [PATCH 061/151] AutoFeatures: Add support for the XPrison enchantments. Please be aware that event priorities must be adjusted. You can change prison's event priorities, but XPrison is hard coded to NORMAL So to get this work, you may have to adjust prison's priorities so it is after XPrison's. We cannot support XPrison especially if their event priorities become a problem, or causes a problem. --- ...toManagerXPrisonExplosionTriggerEvent.java | 433 ++++++++++++++++++ .../AutoManagerXPrisonLayerTriggerEvent.java | 433 ++++++++++++++++++ .../AutoManagerXPrisonNukeTriggerEvent.java | 433 ++++++++++++++++++ 3 files changed, 1299 insertions(+) create mode 100644 prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerXPrisonExplosionTriggerEvent.java create mode 100644 prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerXPrisonLayerTriggerEvent.java create mode 100644 prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerXPrisonNukeTriggerEvent.java diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerXPrisonExplosionTriggerEvent.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerXPrisonExplosionTriggerEvent.java new file mode 100644 index 000000000..63218cbf5 --- /dev/null +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerXPrisonExplosionTriggerEvent.java @@ -0,0 +1,433 @@ +package tech.mcprison.prison.spigot.autofeatures.events; + +import org.bukkit.Bukkit; +import org.bukkit.block.Block; +import org.bukkit.entity.Player; +import org.bukkit.event.Event; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.HandlerList; +import org.bukkit.event.Listener; +import org.bukkit.inventory.ItemStack; +import org.bukkit.plugin.EventExecutor; +import org.bukkit.plugin.PluginManager; + +import dev.drawethree.xprison.enchants.api.events.ExplosionTriggerEvent; +import tech.mcprison.prison.autofeatures.AutoFeaturesFileConfig.AutoFeatures; +import tech.mcprison.prison.autofeatures.AutoFeaturesWrapper; +import tech.mcprison.prison.mines.features.MineBlockEvent.BlockEventType; +import tech.mcprison.prison.output.Output; +import tech.mcprison.prison.spigot.SpigotPrison; +import tech.mcprison.prison.spigot.api.PrisonMinesBlockBreakEvent; +import tech.mcprison.prison.spigot.autofeatures.AutoManagerFeatures; +import tech.mcprison.prison.spigot.block.BlockBreakPriority; + +public class AutoManagerXPrisonExplosionTriggerEvent + extends AutoManagerFeatures + implements PrisonEventManager +{ + + +// private ExplosionTriggerEvent ete; +// private LayerTriggerEvent lte; +// private NukeTriggerEvent nte; + +// dev.drawethree.xprison.enchants.api.events.ExplosionTriggerEvent; + + + + private BlockBreakPriority bbPriority; + + public AutoManagerXPrisonExplosionTriggerEvent() { + super(); + } + + public AutoManagerXPrisonExplosionTriggerEvent( BlockBreakPriority bbPriority ) { + super(); + + this.bbPriority = bbPriority; + } + + + public BlockBreakPriority getBbPriority() { + return bbPriority; + } + public void setBbPriority( BlockBreakPriority bbPriority ) { + this.bbPriority = bbPriority; + } + + @Override + public void registerEvents() { + + if ( AutoFeaturesWrapper.getInstance().isBoolean(AutoFeatures.isAutoManagerEnabled) ) { + + initialize(); + } + } + + + public class AutoManagerXPrisonExplosionTriggerEventListener + extends AutoManagerXPrisonExplosionTriggerEvent + implements Listener { + + public AutoManagerXPrisonExplosionTriggerEventListener( BlockBreakPriority bbPriority ) { + super( bbPriority ); + } + + @EventHandler(priority=EventPriority.NORMAL) + public void onXPrisonExplosionTriggerEvent( + ExplosionTriggerEvent e, BlockBreakPriority bbPriority) { + + if ( isDisabled( e.getPlayer().getLocation().getWorld().getName() ) || + bbPriority.isDisabled() ) { + return; + } + + handleXPrisonExplosionTriggerEvent( e, bbPriority ); + } + } + + + @Override + public void initialize() { + + String eP = getMessage( AutoFeatures.XPrisonExplosionTriggerEventPriority ); + BlockBreakPriority bbPriority = BlockBreakPriority.fromString( eP ); + + setBbPriority( bbPriority ); + +// boolean isEventEnabled = eP != null && !"DISABLED".equalsIgnoreCase( eP ); + + if ( getBbPriority() == BlockBreakPriority.DISABLED ) { + return; + } + + // Check to see if the class ExplosionTriggerEvent even exists: + try { + Output.get().logInfo( "AutoManager: checking if loaded: XPrison ExplosionTriggerEvent" ); + + Class.forName( "dev.drawethree.xprison.enchants.api.events.ExplosionTriggerEvent", false, + this.getClass().getClassLoader() ); + + Output.get().logInfo( "AutoManager: Trying to register XPrison ExplosionTriggerEvent" ); + + if ( getBbPriority() != BlockBreakPriority.DISABLED ) { + if ( bbPriority.isComponentCompound() ) { + + for (BlockBreakPriority subBBPriority : bbPriority.getComponentPriorities()) { + + createListener( subBBPriority ); + } + } + else { + + createListener(bbPriority); + } + + } + } + catch ( ClassNotFoundException e ) { + // CrazyEnchants is not loaded... so ignore. + Output.get().logInfo( "AutoManager: XPrison ExplosionTriggerEvent is not loaded" ); + } + catch ( Exception e ) { + Output.get().logInfo( "AutoManager: XPrison ExplosionTriggerEvent failed to load. [%s]", e.getMessage() ); + } + } + + private void createListener( BlockBreakPriority bbPriority ) { + + SpigotPrison prison = SpigotPrison.getInstance(); + PluginManager pm = Bukkit.getServer().getPluginManager(); + EventPriority ePriority = bbPriority.getBukkitEventPriority(); + + + AutoManagerXPrisonExplosionTriggerEventListener autoManagerListener = + new AutoManagerXPrisonExplosionTriggerEventListener( bbPriority ); + + pm.registerEvent( + ExplosionTriggerEvent.class, + autoManagerListener, ePriority, + new EventExecutor() { + public void execute(Listener l, Event e) { + + ExplosionTriggerEvent exEvent = (ExplosionTriggerEvent) e; + + ((AutoManagerXPrisonExplosionTriggerEventListener)l) + .onXPrisonExplosionTriggerEvent(exEvent, bbPriority); + } + }, + prison); + prison.getRegisteredBlockListeners().add( autoManagerListener ); + } + + + @Override + public void unregisterListeners() { + +// super.unregisterListeners(); + } + + @Override + public void dumpEventListeners() { + + StringBuilder sb = new StringBuilder(); + + dumpEventListeners( sb ); + + if ( sb.length() > 0 ) { + + + for ( String line : sb.toString().split( "\n" ) ) { + + Output.get().logInfo( line ); + } + } + + } + + + @Override + public void dumpEventListeners( StringBuilder sb ) { + + String eP = getMessage( AutoFeatures.XPrisonExplosionTriggerEventPriority ); + boolean isEventEnabled = eP != null && !"DISABLED".equalsIgnoreCase( eP ); + + if ( !isEventEnabled ) { + return; + } + + // Check to see if the class ExplosionTriggerEvent even exists: + try { + + Class.forName( "dev.drawethree.xprison.enchants.api.events.ExplosionTriggerEvent", false, + this.getClass().getClassLoader() ); + + + HandlerList handlers = ExplosionTriggerEvent.getHandlerList(); + +// String eP = getMessage( AutoFeatures.blockBreakEventPriority ); + BlockBreakPriority bbPriority = BlockBreakPriority.fromString( eP ); + + dumpEventListenersCore( "XPrison ExplosionTriggerEvent", handlers, bbPriority, sb ); + + +// +// BlockBreakPriority bbPriority = BlockBreakPriority.fromString( eP ); +// +// +// String title = String.format( +// "ExplosionTriggerEvent (%s)", +// ( bbPriority == null ? "--none--" : bbPriority.name()) ); +// +// ChatDisplay eventDisplay = Prison.get().getPlatform().dumpEventListenersChatDisplay( +// title, +// new SpigotHandlerList( ExplosionTriggerEvent.getHandlerList()) ); +// +// if ( eventDisplay != null ) { +// sb.append( eventDisplay.toStringBuilder() ); +// sb.append( "\n" ); +// } +// +// +// if ( bbPriority.isComponentCompound() ) { +// StringBuilder sbCP = new StringBuilder(); +// for ( BlockBreakPriority bbp : bbPriority.getComponentPriorities() ) { +// if ( sbCP.length() > 0 ) { +// sbCP.append( ", " ); +// } +// sbCP.append( "'" ).append( bbp.name() ).append( "'" ); +// } +// +// String msg = String.format( "Note '%s' is a compound of: [%s]", +// bbPriority.name(), +// sbCP ); +// +// sb.append( msg ).append( "\n" ); +// } + } + catch ( ClassNotFoundException e ) { + // XPrison is not loaded... so ignore. + } + catch ( Exception e ) { + String causedBy = e.getCause() == null ? "" : e.getCause().getMessage(); + + Output.get().logInfo( "AutoManager: XPrison ExplosionTriggerEvent failed to load. " + + "[%s] Caused by: [%s]", + e.getMessage(), + causedBy ); + } + } + + + /** + *

Since there are multiple blocks associated with this event, pull out the player first and + * get the mine, then loop through those blocks to make sure they are within the mine. + *

+ * + *

The logic in this function is slightly different compared to genericBlockEvent() because this + * event contains multiple blocks so it's far more efficient to process the player data once. + * So that basically needed a slight refactoring. + *

+ * + * @param e + */ + public void handleXPrisonExplosionTriggerEvent( ExplosionTriggerEvent e, BlockBreakPriority bbPriority ) { + + PrisonMinesBlockBreakEvent pmEvent = null; + long start = System.nanoTime(); + + // If the event is canceled, it still needs to be processed because of the + // MONITOR events: + // An event will be "canceled" and "ignored" if the block + // BlockUtils.isUnbreakable(), or if the mine is actively resetting. + // The event will also be ignored if the block is outside of a mine + // or if the targetBlock has been set to ignore all block events which + // means the block has already been processed. + MinesEventResults eventResults = ignoreMinesBlockBreakEvent( e, + e.getPlayer(), e.getOriginBlock(), + bbPriority, true ); + + if ( eventResults.isIgnoreEvent() ) { + return; + } + + + StringBuilder debugInfo = new StringBuilder(); + + debugInfo.append( String.format( "### ** handleXPrisonExplosionTriggerEvent ** ### " + + "(event: ExplosionTriggerEvent, config: %s, priority: %s, canceled: %s) ", + bbPriority.name(), + bbPriority.getBukkitEventPriority().name(), + (e.isCancelled() ? "TRUE " : "FALSE") + ) ); + + debugInfo.append( eventResults.getDebugInfo() ); + + + // NOTE that check for auto manager has happened prior to accessing this function. + + // Process all priorities if the event has not been canceled, and + // process the MONITOR priority even if the event was canceled: + if ( !bbPriority.isMonitor() && !e.isCancelled() || + bbPriority.isMonitor() && + e.getBlocksAffected().size() > 0 ) { + + + +// Block bukkitBlock = e.getBlocks().get( 0 ); + + BlockEventType eventType = BlockEventType.XPrisonExplosionTriggerEvent; + String triggered = null; + + + pmEvent = new PrisonMinesBlockBreakEvent( + eventResults, +// bukkitBlock, +// e.getPlayer(), +// eventResults.getMine(), +// bbPriority, + eventType, triggered, + debugInfo ); + + + // NOTE: Check for the ACCESS priority and if someone does not have access, then return + // with a cancel on the event. Both ACCESSBLOCKEVENTS and ACCESSMONITOR will be + // converted to just ACCESS at this point, and the other part will run under either + // BLOCKEVENTS or MONITOR. + // This check has to be performed after creating the pmEvent object since it uses + // a lot of the internal variables and objects. There is not much of an impact since + // the validateEvent() has not been ran yet. + if ( checkIfNoAccess( pmEvent, start ) ) { + + e.setCancelled( true ); + return; + } + + + for ( int i = 1; i < e.getBlocksAffected().size(); i++ ) { + pmEvent.getUnprocessedRawBlocks().add( e.getBlocksAffected().get( i ) ); + } + + + if ( !validateEvent( pmEvent ) ) { + + // The event has not passed validation. All logging and Errors have been recorded + // so do nothing more. This is to just prevent normal processing from occurring. + + if ( pmEvent.isCancelOriginalEvent() ) { + + e.setCancelled( true ); + } + + debugInfo.append( "(doAction failed validation) " ); + } + + + + // The validation was successful, but stop processing for the MONITOR priorities. + // Note that BLOCKEVENTS processing occurred already within validateEvent(): + else if ( pmEvent.getBbPriority().isMonitor() ) { + // Stop here, and prevent additional processing. + // Monitors should never process the event beyond this. + } + + + + // This is where the processing actually happens: + else { + +// debugInfo.append( "(normal processing initiating) " ); + + // check all external events such as mcMMO and EZBlocks: +// if ( e instanceof BlockBreakEvent ) { +// processPMBBExternalEvents( pmEvent, debugInfo, e ); +// } +// + + EventListenerCancelBy cancelBy = EventListenerCancelBy.none; + + cancelBy = processPMBBEvent( pmEvent ); + + + if ( cancelBy != EventListenerCancelBy.none ) { + + e.setCancelled( true ); + debugInfo.append( "(event canceled) " ); + } +// else if ( cancelBy == EventListenerCancelBy.drops ) { +// try +// { +// e.setDropItems( false ); +// debugInfo.append( "(drop canceled) " ); +// } +// catch ( NoSuchMethodError e1 ) +// { +// String message = String.format( +// "Warning: The autoFeaturesConfig.yml setting `cancelAllBlockEventBlockDrops` " + +// "is not valid for this version of Spigot. It's only vaid for spigot v1.12.x and higher. " + +// "Modify the config settings and set this value to `false`. For now, it is temporarily " + +// "disabled. [%s]", +// e1.getMessage() ); +// Output.get().logWarn( message ); +// +// AutoFeaturesWrapper.getInstance().getAutoFeaturesConfig() +// .setFeature( AutoFeatures.cancelAllBlockEventBlockDrops, false ); +// } +// +// } + } + + + } + + printDebugInfo( pmEvent, start ); + } + + @Override + protected int checkBonusXp( Player player, Block block, ItemStack item ) { + int bonusXp = 0; + + return bonusXp; + } +} diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerXPrisonLayerTriggerEvent.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerXPrisonLayerTriggerEvent.java new file mode 100644 index 000000000..42bba739a --- /dev/null +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerXPrisonLayerTriggerEvent.java @@ -0,0 +1,433 @@ +package tech.mcprison.prison.spigot.autofeatures.events; + +import org.bukkit.Bukkit; +import org.bukkit.block.Block; +import org.bukkit.entity.Player; +import org.bukkit.event.Event; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.HandlerList; +import org.bukkit.event.Listener; +import org.bukkit.inventory.ItemStack; +import org.bukkit.plugin.EventExecutor; +import org.bukkit.plugin.PluginManager; + +import dev.drawethree.xprison.enchants.api.events.LayerTriggerEvent; +import tech.mcprison.prison.autofeatures.AutoFeaturesFileConfig.AutoFeatures; +import tech.mcprison.prison.autofeatures.AutoFeaturesWrapper; +import tech.mcprison.prison.mines.features.MineBlockEvent.BlockEventType; +import tech.mcprison.prison.output.Output; +import tech.mcprison.prison.spigot.SpigotPrison; +import tech.mcprison.prison.spigot.api.PrisonMinesBlockBreakEvent; +import tech.mcprison.prison.spigot.autofeatures.AutoManagerFeatures; +import tech.mcprison.prison.spigot.block.BlockBreakPriority; + +public class AutoManagerXPrisonLayerTriggerEvent + extends AutoManagerFeatures + implements PrisonEventManager +{ + + +// private ExplosionTriggerEvent ete; +// private LayerTriggerEvent lte; +// private NukeTriggerEvent nte; + + //dev.drawethree.xprison.enchants.api.events.LayerTriggerEvent; + + + + private BlockBreakPriority bbPriority; + + public AutoManagerXPrisonLayerTriggerEvent() { + super(); + } + + public AutoManagerXPrisonLayerTriggerEvent( BlockBreakPriority bbPriority ) { + super(); + + this.bbPriority = bbPriority; + } + + + public BlockBreakPriority getBbPriority() { + return bbPriority; + } + public void setBbPriority( BlockBreakPriority bbPriority ) { + this.bbPriority = bbPriority; + } + + @Override + public void registerEvents() { + + if ( AutoFeaturesWrapper.getInstance().isBoolean(AutoFeatures.isAutoManagerEnabled) ) { + + initialize(); + } + } + + + public class AutoManagerXPrisonLayerTriggerEventListener + extends AutoManagerXPrisonLayerTriggerEvent + implements Listener { + + public AutoManagerXPrisonLayerTriggerEventListener( BlockBreakPriority bbPriority ) { + super( bbPriority ); + } + + @EventHandler(priority=EventPriority.NORMAL) + public void onXPrisonLayerTriggerEvent( + LayerTriggerEvent e, BlockBreakPriority bbPriority) { + + if ( isDisabled( e.getPlayer().getLocation().getWorld().getName() ) || + bbPriority.isDisabled() ) { + return; + } + + handleXPrisonLayerTriggerEvent( e, bbPriority ); + } + } + + + @Override + public void initialize() { + + String eP = getMessage( AutoFeatures.XPrisonLayerTriggerEventPriority ); + BlockBreakPriority bbPriority = BlockBreakPriority.fromString( eP ); + + setBbPriority( bbPriority ); + + // boolean isEventEnabled = eP != null && !"DISABLED".equalsIgnoreCase( eP ); + + if ( getBbPriority() == BlockBreakPriority.DISABLED ) { + return; + } + + // Check to see if the class LayerTriggerEvent even exists: + try { + Output.get().logInfo( "AutoManager: checking if loaded: XPrison LayerTriggerEvent" ); + + Class.forName( "dev.drawethree.xprison.enchants.api.events.LayerTriggerEvent", false, + this.getClass().getClassLoader() ); + + Output.get().logInfo( "AutoManager: Trying to register XPrison LayerTriggerEvent" ); + + if ( getBbPriority() != BlockBreakPriority.DISABLED ) { + if ( bbPriority.isComponentCompound() ) { + + for (BlockBreakPriority subBBPriority : bbPriority.getComponentPriorities()) { + + createListener( subBBPriority ); + } + } + else { + + createListener(bbPriority); + } + + } + } + catch ( ClassNotFoundException e ) { + // CrazyEnchants is not loaded... so ignore. + Output.get().logInfo( "AutoManager: XPrison LayerTriggerEvent is not loaded" ); + } + catch ( Exception e ) { + Output.get().logInfo( "AutoManager: XPrison LayerTriggerEvent failed to load. [%s]", e.getMessage() ); + } + } + + private void createListener( BlockBreakPriority bbPriority ) { + + SpigotPrison prison = SpigotPrison.getInstance(); + PluginManager pm = Bukkit.getServer().getPluginManager(); + EventPriority ePriority = bbPriority.getBukkitEventPriority(); + + + AutoManagerXPrisonLayerTriggerEventListener autoManagerListener = + new AutoManagerXPrisonLayerTriggerEventListener( bbPriority ); + + pm.registerEvent( + LayerTriggerEvent.class, + autoManagerListener, ePriority, + new EventExecutor() { + public void execute(Listener l, Event e) { + + LayerTriggerEvent exEvent = (LayerTriggerEvent) e; + + ((AutoManagerXPrisonLayerTriggerEventListener)l) + .onXPrisonLayerTriggerEvent(exEvent, bbPriority); + } + }, + prison); + prison.getRegisteredBlockListeners().add( autoManagerListener ); + } + + + @Override + public void unregisterListeners() { + + // super.unregisterListeners(); + } + + @Override + public void dumpEventListeners() { + + StringBuilder sb = new StringBuilder(); + + dumpEventListeners( sb ); + + if ( sb.length() > 0 ) { + + + for ( String line : sb.toString().split( "\n" ) ) { + + Output.get().logInfo( line ); + } + } + + } + + +@Override +public void dumpEventListeners( StringBuilder sb ) { + + String eP = getMessage( AutoFeatures.XPrisonLayerTriggerEventPriority ); + boolean isEventEnabled = eP != null && !"DISABLED".equalsIgnoreCase( eP ); + + if ( !isEventEnabled ) { + return; + } + + // Check to see if the class LayerTriggerEvent even exists: + try { + + Class.forName( "dev.drawethree.xprison.enchants.api.events.LayerTriggerEvent", false, + this.getClass().getClassLoader() ); + + + HandlerList handlers = LayerTriggerEvent.getHandlerList(); + +// String eP = getMessage( AutoFeatures.blockBreakEventPriority ); + BlockBreakPriority bbPriority = BlockBreakPriority.fromString( eP ); + + dumpEventListenersCore( "XPrison LayerTriggerEvent", handlers, bbPriority, sb ); + + +// +// BlockBreakPriority bbPriority = BlockBreakPriority.fromString( eP ); +// +// +// String title = String.format( +// "LayerTriggerEvent (%s)", +// ( bbPriority == null ? "--none--" : bbPriority.name()) ); +// +// ChatDisplay eventDisplay = Prison.get().getPlatform().dumpEventListenersChatDisplay( +// title, +// new SpigotHandlerList( LayerTriggerEvent.getHandlerList()) ); +// +// if ( eventDisplay != null ) { +// sb.append( eventDisplay.toStringBuilder() ); +// sb.append( "\n" ); +// } +// +// +// if ( bbPriority.isComponentCompound() ) { +// StringBuilder sbCP = new StringBuilder(); +// for ( BlockBreakPriority bbp : bbPriority.getComponentPriorities() ) { +// if ( sbCP.length() > 0 ) { +// sbCP.append( ", " ); +// } +// sbCP.append( "'" ).append( bbp.name() ).append( "'" ); +// } +// +// String msg = String.format( "Note '%s' is a compound of: [%s]", +// bbPriority.name(), +// sbCP ); +// +// sb.append( msg ).append( "\n" ); +// } + } + catch ( ClassNotFoundException e ) { + // XPrison is not loaded... so ignore. + } + catch ( Exception e ) { + String causedBy = e.getCause() == null ? "" : e.getCause().getMessage(); + + Output.get().logInfo( "AutoManager: XPrison LayerTriggerEvent failed to load. " + + "[%s] Caused by: [%s]", + e.getMessage(), + causedBy ); + } +} + + +/** + *

Since there are multiple blocks associated with this event, pull out the player first and + * get the mine, then loop through those blocks to make sure they are within the mine. + *

+ * + *

The logic in this function is slightly different compared to genericBlockEvent() because this + * event contains multiple blocks so it's far more efficient to process the player data once. + * So that basically needed a slight refactoring. + *

+ * + * @param e + */ +public void handleXPrisonLayerTriggerEvent( LayerTriggerEvent e, BlockBreakPriority bbPriority ) { + + PrisonMinesBlockBreakEvent pmEvent = null; + long start = System.nanoTime(); + + // If the event is canceled, it still needs to be processed because of the + // MONITOR events: + // An event will be "canceled" and "ignored" if the block + // BlockUtils.isUnbreakable(), or if the mine is actively resetting. + // The event will also be ignored if the block is outside of a mine + // or if the targetBlock has been set to ignore all block events which + // means the block has already been processed. + MinesEventResults eventResults = ignoreMinesBlockBreakEvent( e, + e.getPlayer(), e.getOriginBlock(), + bbPriority, true ); + + if ( eventResults.isIgnoreEvent() ) { + return; + } + + + StringBuilder debugInfo = new StringBuilder(); + + debugInfo.append( String.format( "### ** handleXPrisonLayerTriggerEvent ** ### " + + "(event: LayerTriggerEvent, config: %s, priority: %s, canceled: %s) ", + bbPriority.name(), + bbPriority.getBukkitEventPriority().name(), + (e.isCancelled() ? "TRUE " : "FALSE") + ) ); + + debugInfo.append( eventResults.getDebugInfo() ); + + + // NOTE that check for auto manager has happened prior to accessing this function. + + // Process all priorities if the event has not been canceled, and + // process the MONITOR priority even if the event was canceled: + if ( !bbPriority.isMonitor() && !e.isCancelled() || + bbPriority.isMonitor() && + e.getBlocksAffected().size() > 0 ) { + + + +// Block bukkitBlock = e.getBlocks().get( 0 ); + + BlockEventType eventType = BlockEventType.XPrisonLayerTriggerEvent; + String triggered = null; + + + pmEvent = new PrisonMinesBlockBreakEvent( + eventResults, +// bukkitBlock, +// e.getPlayer(), +// eventResults.getMine(), +// bbPriority, + eventType, triggered, + debugInfo ); + + + // NOTE: Check for the ACCESS priority and if someone does not have access, then return + // with a cancel on the event. Both ACCESSBLOCKEVENTS and ACCESSMONITOR will be + // converted to just ACCESS at this point, and the other part will run under either + // BLOCKEVENTS or MONITOR. + // This check has to be performed after creating the pmEvent object since it uses + // a lot of the internal variables and objects. There is not much of an impact since + // the validateEvent() has not been ran yet. + if ( checkIfNoAccess( pmEvent, start ) ) { + + e.setCancelled( true ); + return; + } + + + for ( int i = 1; i < e.getBlocksAffected().size(); i++ ) { + pmEvent.getUnprocessedRawBlocks().add( e.getBlocksAffected().get( i ) ); + } + + + if ( !validateEvent( pmEvent ) ) { + + // The event has not passed validation. All logging and Errors have been recorded + // so do nothing more. This is to just prevent normal processing from occurring. + + if ( pmEvent.isCancelOriginalEvent() ) { + + e.setCancelled( true ); + } + + debugInfo.append( "(doAction failed validation) " ); + } + + + + // The validation was successful, but stop processing for the MONITOR priorities. + // Note that BLOCKEVENTS processing occurred already within validateEvent(): + else if ( pmEvent.getBbPriority().isMonitor() ) { + // Stop here, and prevent additional processing. + // Monitors should never process the event beyond this. + } + + + + // This is where the processing actually happens: + else { + +// debugInfo.append( "(normal processing initiating) " ); + + // check all external events such as mcMMO and EZBlocks: +// if ( e instanceof BlockBreakEvent ) { +// processPMBBExternalEvents( pmEvent, debugInfo, e ); +// } +// + + EventListenerCancelBy cancelBy = EventListenerCancelBy.none; + + cancelBy = processPMBBEvent( pmEvent ); + + + if ( cancelBy != EventListenerCancelBy.none ) { + + e.setCancelled( true ); + debugInfo.append( "(event canceled) " ); + } +// else if ( cancelBy == EventListenerCancelBy.drops ) { +// try +// { +// e.setDropItems( false ); +// debugInfo.append( "(drop canceled) " ); +// } +// catch ( NoSuchMethodError e1 ) +// { +// String message = String.format( +// "Warning: The autoFeaturesConfig.yml setting `cancelAllBlockEventBlockDrops` " + +// "is not valid for this version of Spigot. It's only vaid for spigot v1.12.x and higher. " + +// "Modify the config settings and set this value to `false`. For now, it is temporarily " + +// "disabled. [%s]", +// e1.getMessage() ); +// Output.get().logWarn( message ); +// +// AutoFeaturesWrapper.getInstance().getAutoFeaturesConfig() +// .setFeature( AutoFeatures.cancelAllBlockEventBlockDrops, false ); +// } +// +// } + } + + + } + + printDebugInfo( pmEvent, start ); +} + + @Override + protected int checkBonusXp( Player player, Block block, ItemStack item ) { + int bonusXp = 0; + + return bonusXp; + } +} diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerXPrisonNukeTriggerEvent.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerXPrisonNukeTriggerEvent.java new file mode 100644 index 000000000..80e60990a --- /dev/null +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerXPrisonNukeTriggerEvent.java @@ -0,0 +1,433 @@ +package tech.mcprison.prison.spigot.autofeatures.events; + +import org.bukkit.Bukkit; +import org.bukkit.block.Block; +import org.bukkit.entity.Player; +import org.bukkit.event.Event; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.HandlerList; +import org.bukkit.event.Listener; +import org.bukkit.inventory.ItemStack; +import org.bukkit.plugin.EventExecutor; +import org.bukkit.plugin.PluginManager; + +import dev.drawethree.xprison.enchants.api.events.NukeTriggerEvent; +import tech.mcprison.prison.autofeatures.AutoFeaturesFileConfig.AutoFeatures; +import tech.mcprison.prison.autofeatures.AutoFeaturesWrapper; +import tech.mcprison.prison.mines.features.MineBlockEvent.BlockEventType; +import tech.mcprison.prison.output.Output; +import tech.mcprison.prison.spigot.SpigotPrison; +import tech.mcprison.prison.spigot.api.PrisonMinesBlockBreakEvent; +import tech.mcprison.prison.spigot.autofeatures.AutoManagerFeatures; +import tech.mcprison.prison.spigot.block.BlockBreakPriority; + +public class AutoManagerXPrisonNukeTriggerEvent + extends AutoManagerFeatures + implements PrisonEventManager +{ + + +// private ExplosionTriggerEvent ete; +// private LayerTriggerEvent lte; +// private NukeTriggerEvent nte; + + //dev.drawethree.xprison.enchants.api.events.NukeTriggerEvent; + + + + private BlockBreakPriority bbPriority; + + public AutoManagerXPrisonNukeTriggerEvent() { + super(); + } + + public AutoManagerXPrisonNukeTriggerEvent( BlockBreakPriority bbPriority ) { + super(); + + this.bbPriority = bbPriority; + } + + + public BlockBreakPriority getBbPriority() { + return bbPriority; + } + public void setBbPriority( BlockBreakPriority bbPriority ) { + this.bbPriority = bbPriority; + } + + @Override + public void registerEvents() { + + if ( AutoFeaturesWrapper.getInstance().isBoolean(AutoFeatures.isAutoManagerEnabled) ) { + + initialize(); + } + } + + +public class AutoManagerXPrisonNukeTriggerEventListener + extends AutoManagerXPrisonNukeTriggerEvent + implements Listener { + + public AutoManagerXPrisonNukeTriggerEventListener( BlockBreakPriority bbPriority ) { + super( bbPriority ); + } + + @EventHandler(priority=EventPriority.NORMAL) + public void onXPrisonNukeTriggerEvent( + NukeTriggerEvent e, BlockBreakPriority bbPriority) { + + if ( isDisabled( e.getPlayer().getLocation().getWorld().getName() ) || + bbPriority.isDisabled() ) { + return; + } + + handleXPrisonNukeTriggerEvent( e, bbPriority ); + } +} + + +@Override +public void initialize() { + + String eP = getMessage( AutoFeatures.XPrisonNukeTriggerEventPriority ); + BlockBreakPriority bbPriority = BlockBreakPriority.fromString( eP ); + + setBbPriority( bbPriority ); + +// boolean isEventEnabled = eP != null && !"DISABLED".equalsIgnoreCase( eP ); + + if ( getBbPriority() == BlockBreakPriority.DISABLED ) { + return; + } + + // Check to see if the class NukeTriggerEvent even exists: + try { + Output.get().logInfo( "AutoManager: checking if loaded: XPrison NukeTriggerEvent" ); + + Class.forName( "dev.drawethree.xprison.enchants.api.events.NukeTriggerEvent", false, + this.getClass().getClassLoader() ); + + Output.get().logInfo( "AutoManager: Trying to register XPrison NukeTriggerEvent" ); + + if ( getBbPriority() != BlockBreakPriority.DISABLED ) { + if ( bbPriority.isComponentCompound() ) { + + for (BlockBreakPriority subBBPriority : bbPriority.getComponentPriorities()) { + + createListener( subBBPriority ); + } + } + else { + + createListener(bbPriority); + } + + } + } + catch ( ClassNotFoundException e ) { + // CrazyEnchants is not loaded... so ignore. + Output.get().logInfo( "AutoManager: XPrison NukeTriggerEvent is not loaded" ); + } + catch ( Exception e ) { + Output.get().logInfo( "AutoManager: XPrison NukeTriggerEvent failed to load. [%s]", e.getMessage() ); + } +} + +private void createListener( BlockBreakPriority bbPriority ) { + + SpigotPrison prison = SpigotPrison.getInstance(); + PluginManager pm = Bukkit.getServer().getPluginManager(); + EventPriority ePriority = bbPriority.getBukkitEventPriority(); + + + AutoManagerXPrisonNukeTriggerEventListener autoManagerListener = + new AutoManagerXPrisonNukeTriggerEventListener( bbPriority ); + + pm.registerEvent( + NukeTriggerEvent.class, + autoManagerListener, ePriority, + new EventExecutor() { + public void execute(Listener l, Event e) { + + NukeTriggerEvent exEvent = (NukeTriggerEvent) e; + + ((AutoManagerXPrisonNukeTriggerEventListener)l) + .onXPrisonNukeTriggerEvent(exEvent, bbPriority); + } + }, + prison); + prison.getRegisteredBlockListeners().add( autoManagerListener ); +} + + +@Override +public void unregisterListeners() { + +// super.unregisterListeners(); +} + +@Override +public void dumpEventListeners() { + + StringBuilder sb = new StringBuilder(); + + dumpEventListeners( sb ); + + if ( sb.length() > 0 ) { + + + for ( String line : sb.toString().split( "\n" ) ) { + + Output.get().logInfo( line ); + } + } + +} + + +@Override +public void dumpEventListeners( StringBuilder sb ) { + + String eP = getMessage( AutoFeatures.XPrisonNukeTriggerEventPriority ); + boolean isEventEnabled = eP != null && !"DISABLED".equalsIgnoreCase( eP ); + + if ( !isEventEnabled ) { + return; + } + + // Check to see if the class NukeTriggerEvent even exists: + try { + + Class.forName( "dev.drawethree.xprison.enchants.api.events.NukeTriggerEvent", false, + this.getClass().getClassLoader() ); + + + HandlerList handlers = NukeTriggerEvent.getHandlerList(); + +// String eP = getMessage( AutoFeatures.blockBreakEventPriority ); + BlockBreakPriority bbPriority = BlockBreakPriority.fromString( eP ); + + dumpEventListenersCore( "XPrison NukeTriggerEvent", handlers, bbPriority, sb ); + + +// +// BlockBreakPriority bbPriority = BlockBreakPriority.fromString( eP ); +// +// +// String title = String.format( +// "NukeTriggerEvent (%s)", +// ( bbPriority == null ? "--none--" : bbPriority.name()) ); +// +// ChatDisplay eventDisplay = Prison.get().getPlatform().dumpEventListenersChatDisplay( +// title, +// new SpigotHandlerList( NukeTriggerEvent.getHandlerList()) ); +// +// if ( eventDisplay != null ) { +// sb.append( eventDisplay.toStringBuilder() ); +// sb.append( "\n" ); +// } +// +// +// if ( bbPriority.isComponentCompound() ) { +// StringBuilder sbCP = new StringBuilder(); +// for ( BlockBreakPriority bbp : bbPriority.getComponentPriorities() ) { +// if ( sbCP.length() > 0 ) { +// sbCP.append( ", " ); +// } +// sbCP.append( "'" ).append( bbp.name() ).append( "'" ); +// } +// +// String msg = String.format( "Note '%s' is a compound of: [%s]", +// bbPriority.name(), +// sbCP ); +// +// sb.append( msg ).append( "\n" ); +// } + } + catch ( ClassNotFoundException e ) { + // XPrison is not loaded... so ignore. + } + catch ( Exception e ) { + String causedBy = e.getCause() == null ? "" : e.getCause().getMessage(); + + Output.get().logInfo( "AutoManager: XPrison NukeTriggerEvent failed to load. " + + "[%s] Caused by: [%s]", + e.getMessage(), + causedBy ); + } +} + + +/** + *

Since there are multiple blocks associated with this event, pull out the player first and + * get the mine, then loop through those blocks to make sure they are within the mine. + *

+ * + *

The logic in this function is slightly different compared to genericBlockEvent() because this + * event contains multiple blocks so it's far more efficient to process the player data once. + * So that basically needed a slight refactoring. + *

+ * + * @param e + */ +public void handleXPrisonNukeTriggerEvent( NukeTriggerEvent e, BlockBreakPriority bbPriority ) { + + PrisonMinesBlockBreakEvent pmEvent = null; + long start = System.nanoTime(); + + // If the event is canceled, it still needs to be processed because of the + // MONITOR events: + // An event will be "canceled" and "ignored" if the block + // BlockUtils.isUnbreakable(), or if the mine is actively resetting. + // The event will also be ignored if the block is outside of a mine + // or if the targetBlock has been set to ignore all block events which + // means the block has already been processed. + MinesEventResults eventResults = ignoreMinesBlockBreakEvent( e, + e.getPlayer(), e.getOriginBlock(), + bbPriority, true ); + + if ( eventResults.isIgnoreEvent() ) { + return; + } + + + StringBuilder debugInfo = new StringBuilder(); + + debugInfo.append( String.format( "### ** handleXPrisonNukeTriggerEvent ** ### " + + "(event: NukeTriggerEvent, config: %s, priority: %s, canceled: %s) ", + bbPriority.name(), + bbPriority.getBukkitEventPriority().name(), + (e.isCancelled() ? "TRUE " : "FALSE") + ) ); + + debugInfo.append( eventResults.getDebugInfo() ); + + + // NOTE that check for auto manager has happened prior to accessing this function. + + // Process all priorities if the event has not been canceled, and + // process the MONITOR priority even if the event was canceled: + if ( !bbPriority.isMonitor() && !e.isCancelled() || + bbPriority.isMonitor() && + e.getBlocksAffected().size() > 0 ) { + + + +// Block bukkitBlock = e.getBlocks().get( 0 ); + + BlockEventType eventType = BlockEventType.XPrisonNukeTriggerEvent; + String triggered = null; + + + pmEvent = new PrisonMinesBlockBreakEvent( + eventResults, +// bukkitBlock, +// e.getPlayer(), +// eventResults.getMine(), +// bbPriority, + eventType, triggered, + debugInfo ); + + + // NOTE: Check for the ACCESS priority and if someone does not have access, then return + // with a cancel on the event. Both ACCESSBLOCKEVENTS and ACCESSMONITOR will be + // converted to just ACCESS at this point, and the other part will run under either + // BLOCKEVENTS or MONITOR. + // This check has to be performed after creating the pmEvent object since it uses + // a lot of the internal variables and objects. There is not much of an impact since + // the validateEvent() has not been ran yet. + if ( checkIfNoAccess( pmEvent, start ) ) { + + e.setCancelled( true ); + return; + } + + + for ( int i = 1; i < e.getBlocksAffected().size(); i++ ) { + pmEvent.getUnprocessedRawBlocks().add( e.getBlocksAffected().get( i ) ); + } + + + if ( !validateEvent( pmEvent ) ) { + + // The event has not passed validation. All logging and Errors have been recorded + // so do nothing more. This is to just prevent normal processing from occurring. + + if ( pmEvent.isCancelOriginalEvent() ) { + + e.setCancelled( true ); + } + + debugInfo.append( "(doAction failed validation) " ); + } + + + + // The validation was successful, but stop processing for the MONITOR priorities. + // Note that BLOCKEVENTS processing occurred already within validateEvent(): + else if ( pmEvent.getBbPriority().isMonitor() ) { + // Stop here, and prevent additional processing. + // Monitors should never process the event beyond this. + } + + + + // This is where the processing actually happens: + else { + +// debugInfo.append( "(normal processing initiating) " ); + + // check all external events such as mcMMO and EZBlocks: +// if ( e instanceof BlockBreakEvent ) { +// processPMBBExternalEvents( pmEvent, debugInfo, e ); +// } +// + + EventListenerCancelBy cancelBy = EventListenerCancelBy.none; + + cancelBy = processPMBBEvent( pmEvent ); + + + if ( cancelBy != EventListenerCancelBy.none ) { + + e.setCancelled( true ); + debugInfo.append( "(event canceled) " ); + } +// else if ( cancelBy == EventListenerCancelBy.drops ) { +// try +// { +// e.setDropItems( false ); +// debugInfo.append( "(drop canceled) " ); +// } +// catch ( NoSuchMethodError e1 ) +// { +// String message = String.format( +// "Warning: The autoFeaturesConfig.yml setting `cancelAllBlockEventBlockDrops` " + +// "is not valid for this version of Spigot. It's only vaid for spigot v1.12.x and higher. " + +// "Modify the config settings and set this value to `false`. For now, it is temporarily " + +// "disabled. [%s]", +// e1.getMessage() ); +// Output.get().logWarn( message ); +// +// AutoFeaturesWrapper.getInstance().getAutoFeaturesConfig() +// .setFeature( AutoFeatures.cancelAllBlockEventBlockDrops, false ); +// } +// +// } + } + + + } + + printDebugInfo( pmEvent, start ); +} + + @Override + protected int checkBonusXp( Player player, Block block, ItemStack item ) { + int bonusXp = 0; + + return bonusXp; + } +} \ No newline at end of file From 03ba06eb01e4600b90cf50654c98c65c2b4bee84 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Fri, 4 Aug 2023 10:37:21 -0400 Subject: [PATCH 062/151] Prison Placeholders: Added support to disable placeholders in disabled worlds. This feature is not enabled by default. Any disabled world in the prisonCommandHandler configs within config.yml, could also shutdown the prison placeholders in that world if enabled. The placeholder text will be replaced with just an empty string. --- docs/changelog_v3.3.x.md | 6 +++ .../placeholders/PlaceholdersStats.java | 23 +++++++++- .../placeholder/SpigotPlaceholders.java | 42 +++++++++++++++++++ prison-spigot/src/main/resources/config.yml | 1 + 4 files changed, 71 insertions(+), 1 deletion(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index f46f58547..1471a29a3 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -17,6 +17,12 @@ These change logs represent the work that has been going on within prison. # 3.3.0-alpha.15c 2023-08-04 +* **Prison Placeholders: Added support to disable placeholders in disabled worlds.** +This feature is not enabled by default. +Any disabled world in the prisonCommandHandler configs within config.yml, could also shutdown the prison placeholders in that world if enabled. +The placeholder text will be replaced with just an empty string. + + * **Prestiges: Bug fix. If no prestige rank, then prevent a NPE on a simple check.** Totally thought this was fixed a while ago? diff --git a/prison-core/src/main/java/tech/mcprison/prison/placeholders/PlaceholdersStats.java b/prison-core/src/main/java/tech/mcprison/prison/placeholders/PlaceholdersStats.java index bee6b1cf0..56ad91a77 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/placeholders/PlaceholdersStats.java +++ b/prison-core/src/main/java/tech/mcprison/prison/placeholders/PlaceholdersStats.java @@ -13,7 +13,10 @@ public class PlaceholdersStats { private static PlaceholdersStats stats; - TreeMap placeholders; + private TreeMap placeholders; + + private int invalidWorldCount = 0; + private PlaceholdersStats() { super(); @@ -154,6 +157,13 @@ public ArrayList generatePlaceholderReport() { } + + results.add( + String.format( "&7Invalid World Usage Total: &3%10s &b(Placeholders replaced with banks)", + iFmt.format( getInvalidWorldCount() ) )); + + + return results; } @@ -174,6 +184,7 @@ public void clearCache(boolean resetCache, boolean removeErrors) { getPlaceholders().remove( key ); } + setInvalidWorldCount( 0 ); Output.get().logInfo( "PlaceholderStats: Cache was purged of %s placeholders. Removed: %s ", resetCache ? "all" : @@ -190,5 +201,15 @@ public TreeMap getPlaceholders() { public void setPlaceholders(TreeMap placeholders) { this.placeholders = placeholders; } + + public int incrementInvalidWorldCount() { + return invalidWorldCount++; + } + public int getInvalidWorldCount() { + return invalidWorldCount; + } + public void setInvalidWorldCount(int invalidWorldCount) { + this.invalidWorldCount = invalidWorldCount; + } } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/placeholder/SpigotPlaceholders.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/placeholder/SpigotPlaceholders.java index d95853d7b..f6d4cc99c 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/placeholder/SpigotPlaceholders.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/placeholder/SpigotPlaceholders.java @@ -25,6 +25,7 @@ import tech.mcprison.prison.ranks.managers.PlayerManager; import tech.mcprison.prison.ranks.managers.RankManager; import tech.mcprison.prison.spigot.SpigotPrison; +import tech.mcprison.prison.spigot.game.SpigotPlayer; public class SpigotPlaceholders implements Placeholders { @@ -70,6 +71,38 @@ private void initializePlaceholderManagers() { } } + private boolean ignorePlayerInDisabledWorlds( SpigotPlayer sPlayer ) { + boolean results = false; + + String worldName = + sPlayer == null || + sPlayer.getLocation() == null || + sPlayer.getLocation().getWorld() == null ? + null : + sPlayer.getLocation().getWorld().getName(); + + if ( worldName != null && sPlayer.isOnline() ) { + + boolean disable = Prison.get().getPlatform().getConfigBooleanFalse( + "prisonCommandHandler.disable-player-placeholders-in-excluded-worlds" ); + if ( disable ) { + List excludedWorlds = Prison.get().getPlatform() + .getConfigStringArray( "prisonCommandHandler.exclude-worlds" ); + for (String world : excludedWorlds) { + if ( world.trim().equalsIgnoreCase( worldName ) ) { + results = true; + break; + } + } + } + } + + if ( results ) { + PlaceholdersStats.getInstance().incrementInvalidWorldCount(); + } + + return results; + } @Override public Map getPlaceholderDetailCounts() { @@ -425,6 +458,11 @@ private String replaceAllPlaceholders(UUID playerUuid, String playerName, String String replacementText = processPlaceholderIdentifier(identifier); if ( identifier.isFoundAMatch() ) { + + if ( ignorePlayerInDisabledWorlds( (SpigotPlayer) identifier.getPlayer() )) { + replacementText = ""; + } + results = results.replace( placeholderText, replacementText ); } @@ -481,6 +519,10 @@ public List placeholderSearch( UUID playerUuid, String playerName, Strin String value = processPlaceholderHavePlaceholderKey( identifier ); + if ( ignorePlayerInDisabledWorlds( (SpigotPlayer) identifier.getPlayer() )) { + value = ""; + } + // Note: STATSMINES will not work here since the sequence is not being addressed. // if ( mm != null && (placeHolderKey.getPlaceholder().hasFlag( PlaceholderFlags.MINES ) || diff --git a/prison-spigot/src/main/resources/config.yml b/prison-spigot/src/main/resources/config.yml index c9d9ede8a..6d1958918 100644 --- a/prison-spigot/src/main/resources/config.yml +++ b/prison-spigot/src/main/resources/config.yml @@ -418,6 +418,7 @@ prisonCommandHandler: exclude-worlds: - miniGameWorld - playerPlotWorld + disable-player-placeholders-in-excluded-worlds: false exclude-non-ops: exclude-related-aliases: true commands: From 0a1b619d401d448ac7752720024202a97ba1f023 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Fri, 4 Aug 2023 10:43:53 -0400 Subject: [PATCH 063/151] AutoFeatures: Added support for XPrison's enchantments... forgot to add the API jar which is used to just compile prison (not used on servers). --- docs/changelog_v3.3.x.md | 3 +++ .../lib/XPrison-api-1.12.13-RELEASE.jar | Bin 0 -> 13166 bytes 2 files changed, 3 insertions(+) create mode 100644 prison-spigot/lib/XPrison-api-1.12.13-RELEASE.jar diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 1471a29a3..e8d8246a1 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -17,6 +17,9 @@ These change logs represent the work that has been going on within prison. # 3.3.0-alpha.15c 2023-08-04 +* **AutoFeatures: Added support for XPrison's enchantments... forgot to add the API jar which is used to just compile prison (not used on servers).** + + * **Prison Placeholders: Added support to disable placeholders in disabled worlds.** This feature is not enabled by default. Any disabled world in the prisonCommandHandler configs within config.yml, could also shutdown the prison placeholders in that world if enabled. diff --git a/prison-spigot/lib/XPrison-api-1.12.13-RELEASE.jar b/prison-spigot/lib/XPrison-api-1.12.13-RELEASE.jar new file mode 100644 index 0000000000000000000000000000000000000000..6ae3be4daa734dfecd75a59a7539f41900c1a5e1 GIT binary patch literal 13166 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 Date: Tue, 8 Aug 2023 02:08:58 -0400 Subject: [PATCH 064/151] Auto Features: If autosell is enabled and there are any leftover blocks that was not sold, it will now generate an error message and if prison debug mode is turned off, then it will force the logging of the transaction. This forcing the logging can be turned off in the auto features configs. Expanded the logging to change the color on some of the more important warnings and failures so they stand out. Also reworked some of the log details to eliminate redundancy and clarify what's being logged. --- docs/changelog_v3.3.x.md | 7 ++- .../autofeatures/AutoFeaturesFileConfig.java | 7 +++ .../tech/mcprison/prison/output/Output.java | 26 +++++++-- .../api/PrisonMinesBlockBreakEvent.java | 32 ++++++++++- .../autofeatures/AutoManagerFeatures.java | 53 ++++++++++++++++--- .../AutoManagerXPrisonLayerTriggerEvent.java | 2 + .../spigot/block/OnBlockBreakEventCore.java | 32 ++++++++++- .../spigot/block/OnBlockBreakMines.java | 8 +-- 8 files changed, 148 insertions(+), 19 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index e8d8246a1..da0e6c2e3 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -14,7 +14,12 @@ These change logs represent the work that has been going on within prison. -# 3.3.0-alpha.15c 2023-08-04 +# 3.3.0-alpha.15c 2023-08-08 + +* **Auto Features: If autosell is enabled and there are any leftover blocks that was not sold, it will now generate an error message and if prison debug mode is turned off, then it will force the logging of the transaction.** +This forcing the logging can be turned off in the auto features configs. +Expanded the logging to change the color on some of the more important warnings and failures so they stand out. +Also reworked some of the log details to eliminate redundancy and clarify what's being logged. * **AutoFeatures: Added support for XPrison's enchantments... forgot to add the API jar which is used to just compile prison (not used on servers).** diff --git a/prison-core/src/main/java/tech/mcprison/prison/autofeatures/AutoFeaturesFileConfig.java b/prison-core/src/main/java/tech/mcprison/prison/autofeatures/AutoFeaturesFileConfig.java index b8d92591d..c4a8c4180 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/autofeatures/AutoFeaturesFileConfig.java +++ b/prison-core/src/main/java/tech/mcprison/prison/autofeatures/AutoFeaturesFileConfig.java @@ -190,6 +190,13 @@ public enum AutoFeatures { "If OP then you cannot use this permission node since it would always " + "be enabled. Using a value of 'disable' will turn it off for everyone."), // + isAutoSellLeftoversForceDebugLogging(inventory, true), + isAutoSellLeftoversForceDebugLogging__ReadMe(inventory, + "If autosell is enabled and could not sell all blocks, then force " + + "Prison's debug logging of transaction to help identify why. This only " + + "applies if debug mode is turned off."), + + // isAutoSellPerBlockBreakInlinedEnabled(general, false), isAutoSellIfInventoryIsFull(inventory, true), diff --git a/prison-core/src/main/java/tech/mcprison/prison/output/Output.java b/prison-core/src/main/java/tech/mcprison/prison/output/Output.java index 7b19517d0..03d11b301 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/output/Output.java +++ b/prison-core/src/main/java/tech/mcprison/prison/output/Output.java @@ -52,10 +52,10 @@ public class Output private String prefixTemplateError; private String prefixTemplateDebug; - private String colorCodeInfo; - private String colorCodeWarning; - private String colorCodeError; - private String colorCodeDebug; + private final String colorCodeInfo; + private final String colorCodeWarning; + private final String colorCodeError; + private final String colorCodeDebug; private boolean debug = false; @@ -622,4 +622,22 @@ private String gen(String name) { return String.format(prefixTemplate, name); } + + public String getColorCodeInfo() { + return colorCodeInfo; + } + + public String getColorCodeWarning() { + return colorCodeWarning; + } + + public String getColorCodeError() { + return colorCodeError; + } + + public String getColorCodeDebug() { + return colorCodeDebug; + } + + } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/api/PrisonMinesBlockBreakEvent.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/api/PrisonMinesBlockBreakEvent.java index f0e4535e2..5a8b734bd 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/api/PrisonMinesBlockBreakEvent.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/api/PrisonMinesBlockBreakEvent.java @@ -13,6 +13,7 @@ import tech.mcprison.prison.internal.block.PrisonBlock.PrisonBlockType; import tech.mcprison.prison.mines.data.Mine; import tech.mcprison.prison.mines.features.MineBlockEvent.BlockEventType; +import tech.mcprison.prison.output.Output; import tech.mcprison.prison.spigot.block.BlockBreakPriority; import tech.mcprison.prison.spigot.block.SpigotBlock; import tech.mcprison.prison.spigot.block.SpigotItemStack; @@ -129,8 +130,9 @@ public class PrisonMinesBlockBreakEvent private StringBuilder debugInfo; - + private boolean forceDebugLogging; + public PrisonMinesBlockBreakEvent( MinesEventResults eventResults, // Block theBlock, Player player, @@ -175,7 +177,11 @@ public PrisonMinesBlockBreakEvent( this.bukkitDrops = new ArrayList<>(); - this.debugInfo = debugInfo; + this.debugInfo = new StringBuilder(); + setDebugColorCodeDebug(); + this.debugInfo.append( debugInfo ); + + this.forceDebugLogging = false; } @@ -433,4 +439,26 @@ public void setDebugInfo(StringBuilder debugInfo) { this.debugInfo = debugInfo; } + public boolean isForceDebugLogging() { + return forceDebugLogging; + } + public void setForceDebugLogging(boolean forceDebugLogging) { + this.forceDebugLogging = forceDebugLogging; + } + + public void setDebugColorCodeInfo() { + getDebugInfo().append( Output.get().getColorCodeInfo() ); + } + + public void setDebugColorCodeWarning() { + getDebugInfo().append( Output.get().getColorCodeWarning() ); + } + + public void setDebugColorCodeError() { + getDebugInfo().append( Output.get().getColorCodeError() ); + } + + public void setDebugColorCodeDebug() { + getDebugInfo().append( Output.get().getColorCodeDebug() ); + } } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerFeatures.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerFeatures.java index 122576d55..7c97ddb9b 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerFeatures.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerFeatures.java @@ -154,7 +154,15 @@ protected void printDebugInfo( PrisonMinesBlockBreakEvent pmEvent, double start long stop = System.nanoTime(); pmEvent.getDebugInfo().append( " [" ).append( (stop - start) / 1000000d ).append( " ms]" ); - Output.get().logDebug( DebugTarget.blockBreak, pmEvent.getDebugInfo().toString() ); + if ( !Output.get().isDebug() && pmEvent.isForceDebugLogging() ) { + + pmEvent.getDebugInfo().insert(0, Output.get().getColorCodeDebug() ); + Output.get().logInfo( pmEvent.getDebugInfo().toString() ); + } + else { + + Output.get().logDebug( DebugTarget.blockBreak, pmEvent.getDebugInfo().toString() ); + } } } @@ -236,7 +244,7 @@ protected EventListenerCancelBy processPMBBEvent(PrisonMinesBlockBreakEvent pmEv if ( pmEvent.getMine() != null || pmEvent.getMine() == null && !isBoolean( AutoFeatures.pickupLimitToMines ) ) { - pmEvent.getDebugInfo().append( "(normal processing initiating) " ); + pmEvent.getDebugInfo().append( "(Fire pmEvent) " ); // Set the mine's PrisonBlockTypes for the block. Used to identify custom blocks. // Needed since processing of the block will lose track of which mine it came from. @@ -256,8 +264,11 @@ protected EventListenerCancelBy processPMBBEvent(PrisonMinesBlockBreakEvent pmEv // pmEvent.getMine(), sBlock, explodedBlocks, BlockEventType.blockBreak, triggered ); Bukkit.getServer().getPluginManager().callEvent( pmEvent ); if ( pmEvent.isCancelled() ) { + + pmEvent.setDebugColorCodeWarning(); pmEvent.getDebugInfo().append( - "(normal processing: PrisonMinesBlockBreakEvent was canceled by another plugin!) " ); + "(Fire pmEvent: PrisonMinesBlockBreakEvent was canceled by another plugin!) " ); + pmEvent.setDebugColorCodeDebug(); } else { @@ -287,17 +298,19 @@ protected EventListenerCancelBy processPMBBEvent(PrisonMinesBlockBreakEvent pmEv } else { - pmEvent.getDebugInfo().append( "(doAction failed without details) " ); + pmEvent.setDebugColorCodeWarning(); + pmEvent.getDebugInfo().append( "(fire pmEvent:doAction failed without details) " ); + pmEvent.setDebugColorCodeDebug(); } } - pmEvent.getDebugInfo().append( "(normal processing completed) " ); + pmEvent.getDebugInfo().append( "(Fire pmEvent completed) " ); } else { - pmEvent.getDebugInfo().append( "(logic bypass) " ); + pmEvent.getDebugInfo().append( "(Fire pmEvent bypassed) " ); } return cancelBy; } @@ -906,7 +919,9 @@ protected int autoPickup( PrisonMinesBlockBreakEvent pmEvent, else { // Unable to sell since amount was zero. Not configured to be sold. + pmEvent.setDebugColorCodeWarning(); debugInfo.append( "(unsellable: " + itemStack.getName() + " qty: " + itemStack.getAmount() + ") "); + pmEvent.setDebugColorCodeDebug(); autosellUnsellableCount += itemStack.getAmount(); } @@ -918,6 +933,32 @@ protected int autoPickup( PrisonMinesBlockBreakEvent pmEvent, // it will have an amount of more than 0. if ( itemStack.getAmount() > 0 ) { + + // AutoSell failure... some items may be unsellable due to not being setup in the sellall shop: + if ( forceAutoSell || autoSellBySettings || autoSellByPerm ) { + + // Force debug printing for this entry even if debug mode is turned off: + pmEvent.setForceDebugLogging( true ); + + if ( !Output.get().isDebug() && + isBoolean(AutoFeatures.isAutoSellLeftoversForceDebugLogging) ) { + pmEvent.setForceDebugLogging( true ); + } + + pmEvent.setDebugColorCodeError(); + + // Just get the calculated value for the drops... do not sell: + double amount = SellAllUtil.get().getItemStackValue( pmEvent.getSpigotPlayer(), itemStack ); + autosellTotal += amount; + + debugInfo.append( "(WARNING: autosell leftovers: " + itemStack.getName() + + " qty: " + itemStack.getAmount() + " value: " + dFmt.format( amount ) + + " - " + + ( amount == 0 ? " Items NOT in sellall shop!" : " CouldNotSell?") + + ") "); + pmEvent.setDebugColorCodeDebug(); + } + if ( Output.get().isDebug() && isSellallEnabled ) { // Just get the calculated value for the drops... do not sell: diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerXPrisonLayerTriggerEvent.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerXPrisonLayerTriggerEvent.java index 42bba739a..e64aa802d 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerXPrisonLayerTriggerEvent.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerXPrisonLayerTriggerEvent.java @@ -360,7 +360,9 @@ public void handleXPrisonLayerTriggerEvent( LayerTriggerEvent e, BlockBreakPrior e.setCancelled( true ); } + pmEvent.setDebugColorCodeWarning(); debugInfo.append( "(doAction failed validation) " ); + pmEvent.setDebugColorCodeDebug(); } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/block/OnBlockBreakEventCore.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/block/OnBlockBreakEventCore.java index 3a0e7736c..124f0fdc8 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/block/OnBlockBreakEventCore.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/block/OnBlockBreakEventCore.java @@ -276,7 +276,7 @@ protected void finalizeBreakTheBlocks( PrisonMinesBlockBreakEvent pmEvent ) int count = 0; for ( SpigotBlock spigotBlock : blocks ) { - if ( count++ % 10 == 0 && pmEvent.getMine() != null && + if ( count++ % 20 == 0 && pmEvent.getMine() != null && !pmEvent.getMine().getMineStateMutex().isMinable() ) { SpigotPlayer sPlayer = pmEvent.getSpigotPlayer(); @@ -398,7 +398,9 @@ protected boolean validateEvent( PrisonMinesBlockBreakEvent pmEvent ) // NOTE: I have no idea why 25 blocks and less should be bypassed for validation: boolean bypassMatchedBlocks = pmEvent.getMine().getBounds().getTotalBlockCount() <= 25; if ( bypassMatchedBlocks ) { + pmEvent.setDebugColorCodeWarning(); debugInfo.append( "(TargetBlock match requirement is disabled [blocks<=25]) " ); + pmEvent.setDebugColorCodeDebug(); } boolean matchedBlocks = isBlockAMatch( targetBlock, sBlockHit ); @@ -422,6 +424,8 @@ protected boolean validateEvent( PrisonMinesBlockBreakEvent pmEvent ) targetBlock.isExploded()) ) { // debugInfo.setLength( 0 ); + + pmEvent.setDebugColorCodeWarning(); debugInfo.append( "(Primary TargetBlock forcedFastFail validateEvent [ "); if ( targetBlock.isIgnoreAllBlockEvents() ) { debugInfo.append( "ignoreAllBlockEvents " ); @@ -430,6 +434,7 @@ protected boolean validateEvent( PrisonMinesBlockBreakEvent pmEvent ) debugInfo.append( "alreadyExploded" ); } debugInfo.append( "]) " ); + pmEvent.setDebugColorCodeDebug(); pmEvent.setForceIfAirBlock( false ); @@ -530,7 +535,9 @@ protected boolean validateEvent( PrisonMinesBlockBreakEvent pmEvent ) // This block has already been mined and is not a mine bomb, so fail the validation // and cancel the event since if it's not an air block, it may be another effect that // is placing a block within the mine, such as a prison util's decay function. + pmEvent.setDebugColorCodeWarning(); debugInfo.append( "VALIDATION_FAILED_BLOCK_ALREADY_MINED " ); + pmEvent.setDebugColorCodeDebug(); results = false; @@ -542,7 +549,9 @@ protected boolean validateEvent( PrisonMinesBlockBreakEvent pmEvent ) else { noTargetBlock++; + pmEvent.setDebugColorCodeWarning(); debugInfo.append( "VALIDATION_FAILED_NO_TARGETBLOCK " ); + pmEvent.setDebugColorCodeDebug(); results = false; } @@ -676,8 +685,10 @@ else if ( targetExplodedBlock.isMined() ) { } if ( unbreakable > 0 ) { + pmEvent.setDebugColorCodeWarning(); debugInfo.append( "UNBREAKABLE_BLOCK_UTILS (" + unbreakable + " blocks, event not canceled) " ); + pmEvent.setDebugColorCodeDebug(); } if ( outsideOfMine > 0 ) { @@ -701,8 +712,10 @@ else if ( targetExplodedBlock.isMined() ) { } if ( blockTypeNotExpected > 0 ) { + pmEvent.setDebugColorCodeWarning(); debugInfo.append( "BLOCK_TYPE_NOT_EXPECTED__CANNOT_PROCESS (" + blockTypeNotExpected + " ) " ); + pmEvent.setDebugColorCodeDebug(); } @@ -730,7 +743,9 @@ else if ( targetExplodedBlock.isMined() ) { // Ignore event and clear debugInfo: // debugInfo.setLength( 0 ); + pmEvent.setDebugColorCodeWarning(); debugInfo.append( "(TargetBlock forcedFastFail validateEvent [BlockAlreadyMined]) " ); + pmEvent.setDebugColorCodeDebug(); return results; } @@ -754,14 +769,18 @@ else if ( targetExplodedBlock.isMined() ) { // "&cYour tool is worn-out and cannot be used." ); pmEvent.setCancelOriginalEvent( true ); + pmEvent.setDebugColorCodeWarning(); debugInfo.append( "UNUSABLE_TOOL__WORN_OUT (event canceled) " ); + pmEvent.setDebugColorCodeDebug(); results = false; } if ( mine != null && BlockUtils.getInstance().isUnbreakable( sBlockHit ) ) { // The block is unbreakable because a utility has it locked: pmEvent.setCancelOriginalEvent( true ); + pmEvent.setDebugColorCodeWarning(); debugInfo.append( "UNBREAKABLE_BLOCK_UTILS (event canceled) " ); + pmEvent.setDebugColorCodeDebug(); results = false; } if ( mine != null && (mine.isMineAccessByRank() || mine.isAccessPermissionEnabled()) && @@ -773,9 +792,11 @@ else if ( targetExplodedBlock.isMined() ) { mine.isAccessPermissionEnabled() ? "Perms" : "Other?"; pmEvent.setCancelOriginalEvent( true ); + pmEvent.setDebugColorCodeWarning(); debugInfo.append( "ACCESS_DENIED (event canceled - Access by " ) .append( accessType ) .append( ") " ); + pmEvent.setDebugColorCodeDebug(); results = false; } @@ -850,7 +871,9 @@ else if ( targetExplodedBlock.isMined() ) { else if ( results && pmEvent.getBbPriority().isMonitor() && mine == null ) { // bypass all processing since the block break is outside any mine: + pmEvent.setDebugColorCodeWarning(); debugInfo.append( "(MONITOR bypassed: no mine) " ); + pmEvent.setDebugColorCodeDebug(); results = false; } @@ -976,7 +999,9 @@ else if ( results && pmEvent.getBbPriority().isMonitor() && mine != null ) { debugInfo.append( "(PassedValidation) " ); } else { + pmEvent.setDebugColorCodeWarning(); debugInfo.append( "(ValidationFailed) " ); + pmEvent.setDebugColorCodeDebug(); } @@ -1240,7 +1265,9 @@ public boolean applyDropsBlockBreakage( PrisonMinesBlockBreakEvent pmEvent, int success = true; } else { + pmEvent.setDebugColorCodeWarning(); pmEvent.getDebugInfo().append( "(fail:totalDrops=0) "); + pmEvent.setDebugColorCodeDebug(); } return success; @@ -1714,7 +1741,8 @@ protected int getDurabilityResistance(SpigotItemStack itemInHand, String itemLor try { results += Integer.parseInt(val); } catch (NumberFormatException e1) { - Output.get().logError("AutoManager: tool durability failure. lore= [" + s + "] val= [" + val + "] error: " + e1.getMessage()); + Output.get().logError("AutoManager: tool durability failure. " + + "lore= [" + s + "] val= [" + val + "] error: " + e1.getMessage()); } break; diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/block/OnBlockBreakMines.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/block/OnBlockBreakMines.java index 382a535fb..9d297879c 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/block/OnBlockBreakMines.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/block/OnBlockBreakMines.java @@ -92,9 +92,9 @@ public void logDebugInfo() { "" : getSpigotBlock().getLocation().toWorldCoordinates(); - Output.get().logInfo( "Prison AutoFeatures Fast-Fail: %s %s %s %s %s%s", + Output.get().logInfo( "Prison AutoFeatures Fast-Fail: %s %s %s %s%s", getResultsReason().name(), - getBbPriority().name(), + //getBbPriority().name(), getSpigotPlayer().getName(), getMine() == null ? "noMine" : getMine().getName(), @@ -115,9 +115,9 @@ public String getDebugInfo() { getSpigotBlock().getLocation().toWorldCoordinates(); return String.format( - "AutoFeatures: %s %s %s %s %s%s ", + "AutoFeatures: %s %s %s %s%s ", getResultsReason().name(), - getBbPriority().name(), +// getBbPriority().name(), getSpigotPlayer().getName(), getMine() == null ? "noMine" : getMine().getName(), From a1cb8956e78996a6496f7f8c1e2547cb2feaa14b Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Fri, 11 Aug 2023 19:51:28 -0400 Subject: [PATCH 065/151] auto features: Add the calculated autosell to the dropExtra function to force autosell if it should happen to have extra drops left over (it never should). --- .../mcprison/prison/spigot/SpigotPlatform.java | 18 ++++++++++++------ .../autofeatures/AutoManagerFeatures.java | 13 +++++++++---- .../block/OnBlockBreakPlayerManualCore.java | 10 ++++++---- 3 files changed, 27 insertions(+), 14 deletions(-) diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/SpigotPlatform.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/SpigotPlatform.java index 31ffd82cb..591c7a5a1 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/SpigotPlatform.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/SpigotPlatform.java @@ -412,11 +412,13 @@ else if ( oPlayer == null || oPlayer.getName() == null ) { return plugin.getDescription().getVersion(); } - @Override public File getPluginDirectory() { + @Override + public File getPluginDirectory() { return plugin.getDataFolder(); } - @Override public void registerCommand(PluginCommand command) { + @Override + public void registerCommand(PluginCommand command) { try { Command cmd = new Command( command.getLabel(), @@ -560,15 +562,18 @@ public PluginCommand findCommand( String label ) { return results; } - @Override public List getCommands() { + @Override + public List getCommands() { return commands; } - @Override public void dispatchCommand(String cmd) { + @Override + public void dispatchCommand(String cmd) { Bukkit.getServer().dispatchCommand(Bukkit.getConsoleSender(), cmd); } - @Override public void dispatchCommand(tech.mcprison.prison.internal.CommandSender sender, String cmd) { + @Override + public void dispatchCommand(tech.mcprison.prison.internal.CommandSender sender, String cmd) { if ( sender instanceof SpigotCommandSender ) { SpigotCommandSender cmdSender = (SpigotCommandSender) sender; @@ -585,7 +590,8 @@ public PluginCommand findCommand( String label ) { } - @Override public Scheduler getScheduler() { + @Override + public Scheduler getScheduler() { return plugin.scheduler; } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerFeatures.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerFeatures.java index 7c97ddb9b..68d2e69e0 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerFeatures.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerFeatures.java @@ -881,13 +881,16 @@ protected int autoPickup( PrisonMinesBlockBreakEvent pmEvent, !"disable".equalsIgnoreCase( getMessage( AutoFeatures.permissionAutoSellPerBlockBreakEnabled ) ) && player.hasPermission( getMessage( AutoFeatures.permissionAutoSellPerBlockBreakEnabled ) ); + // Try to autosell if enabled in any of the following ways: + boolean autoSell = ( forceAutoSell || autoSellBySettings || autoSellByPerm ); + for ( SpigotItemStack itemStack : drops ) { count += itemStack.getAmount(); // Try to autosell if enabled in any of the following ways: - if ( forceAutoSell || autoSellBySettings || autoSellByPerm ) { + if ( autoSell ) { // // Try to autosell if enabled: // if ( isSellallEnabled && @@ -992,7 +995,7 @@ protected int autoPickup( PrisonMinesBlockBreakEvent pmEvent, // } - dropExtra( extras, player, debugInfo ); + dropExtra( extras, player, debugInfo, autoSell ); // dropExtra( player.getInventory().addItem(itemStack), player, block ); } @@ -1388,7 +1391,8 @@ protected boolean checkLore( SpigotItemStack itemInHand, String loreValue ) { * @param player * @param block */ - protected void dropExtra( HashMap extra, Player player, StringBuilder debugInfo ) { + protected void dropExtra( HashMap extra, + Player player, StringBuilder debugInfo, boolean autoSell ) { if ( SpigotPrison.getInstance().isSellAllEnabled() && ( extra != null && extra.size() > 0 || @@ -1418,7 +1422,8 @@ protected void dropExtra( HashMap extra, Player player // the sellall configs, or the auto feature configs. if (sellAllUtil != null && ( sellAllUtil.isAutoSellEnabled || - isBoolean(AutoFeatures.isAutoSellIfInventoryIsFull) )) { + autoSell )) { +// isBoolean(AutoFeatures.isAutoSellIfInventoryIsFull) )) { if ( isPlayerAutosellEnabled ) { diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/block/OnBlockBreakPlayerManualCore.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/block/OnBlockBreakPlayerManualCore.java index 4ea130819..5d5e0f551 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/block/OnBlockBreakPlayerManualCore.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/block/OnBlockBreakPlayerManualCore.java @@ -267,12 +267,13 @@ protected void autoFeatureBlock( Player p, XMaterial source, StringBuilder debug - protected void autoSmelt( boolean autoSmelt, XMaterial source, XMaterial target, Player p, StringBuilder debugInfo ) { + protected void autoSmelt( boolean autoSmelt, XMaterial source, XMaterial target, + Player p, StringBuilder debugInfo ) { if ( autoSmelt && source != null && target != null ) { HashMap overflow = SpigotUtil.itemStackReplaceItems( p, source, target, 1 ); - dropExtra( overflow, p, debugInfo ); + dropExtra( overflow, p, debugInfo, false ); } } @@ -283,11 +284,12 @@ protected void autoBlock( boolean autoBlock, XMaterial source, XMaterial target, } - protected void autoBlock( boolean autoBlock, XMaterial source, XMaterial target, int ratio, Player p, StringBuilder debugInfo ) { + protected void autoBlock( boolean autoBlock, XMaterial source, XMaterial target, int ratio, + Player p, StringBuilder debugInfo ) { if ( autoBlock && source != null && target != null ) { HashMap overflow = SpigotUtil.itemStackReplaceItems( p, source, target, ratio ); - dropExtra( overflow, p, debugInfo ); + dropExtra( overflow, p, debugInfo, false ); } } From cb7fc8acb27a83bde779b8412e383ec9b6e21684 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sun, 13 Aug 2023 00:11:37 -0400 Subject: [PATCH 066/151] AutoFeatures SellAll: Added the ability to disable the "nothing to sell" message without effecting the other settings. --- docs/changelog_v3.3.x.md | 9 ++- .../prison/spigot/sellall/SellAllUtil.java | 55 +++++++++++++------ 2 files changed, 47 insertions(+), 17 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index da0e6c2e3..280dab766 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -14,7 +14,14 @@ These change logs represent the work that has been going on within prison. -# 3.3.0-alpha.15c 2023-08-08 +# 3.3.0-alpha.15c 2023-08-13 + + +* **AutoFeatures SellAll: Added the ability to disable the "nothing to sell" message without effecting the other settings.** + + +* **auto features: Add the calculated autosell to the dropExtra function to force autosell if it should happen to have extra drops left over (it never should).** + * **Auto Features: If autosell is enabled and there are any leftover blocks that was not sold, it will now generate an error message and if prison debug mode is turned off, then it will force the logging of the transaction.** This forcing the logging can be turned off in the auto features configs. diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/sellall/SellAllUtil.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/sellall/SellAllUtil.java index 8927c8b30..e38bfcfd2 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/sellall/SellAllUtil.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/sellall/SellAllUtil.java @@ -2295,25 +2295,49 @@ public boolean setDelay(int delay){ * @return boolean If successful * */ public boolean sellAllSell(Player p, - boolean isUsingSign, boolean completelySilent, + boolean isUsingSign, + boolean completelySilent, boolean notifyPlayerEarned, - boolean notifyPlayerDelay, boolean notifyPlayerEarningDelay, + boolean notifyPlayerDelay, + boolean notifyPlayerEarningDelay, boolean playSoundOnSellAll) { - return sellAllSell( p, isUsingSign, completelySilent, notifyPlayerEarned, notifyPlayerDelay, - notifyPlayerEarningDelay, playSoundOnSellAll, null ); + return sellAllSell( p, isUsingSign, completelySilent, + notifyPlayerEarned, notifyPlayerDelay, + notifyPlayerEarningDelay, playSoundOnSellAll, + true, + null ); } public boolean sellAllSell(Player p, - boolean isUsingSign, boolean completelySilent, + boolean isUsingSign, + boolean completelySilent, boolean notifyPlayerEarned, - boolean notifyPlayerDelay, boolean notifyPlayerEarningDelay, - boolean playSoundOnSellAll, List amounts ){ + boolean notifyPlayerDelay, + boolean notifyPlayerEarningDelay, + boolean playSoundOnSellAll, + List amounts ) { + + return sellAllSell( p, isUsingSign, completelySilent, + notifyPlayerEarned, notifyPlayerDelay, + notifyPlayerEarningDelay, playSoundOnSellAll, + true, + amounts ); + } + + public boolean sellAllSell(Player p, + boolean isUsingSign, + boolean completelySilent, + boolean notifyPlayerEarned, + boolean notifyPlayerDelay, + boolean notifyPlayerEarningDelay, + boolean playSoundOnSellAll, + boolean notifyNothingToSell, + List amounts ) { if (!isUsingSign && isSellAllSignEnabled && isSellAllBySignOnlyEnabled && !p.hasPermission(permissionBypassSign)){ if (!completelySilent) { sellallCanOnlyUseSignsMsg( new SpigotCommandSender(p) ); -// Output.get().sendWarn(new SpigotPlayer(p), messages.getString(MessagesConfig.StringID.spigot_message_sellall_sell_sign_only)); } return false; } @@ -2322,7 +2346,6 @@ public boolean sellAllSell(Player p, if (notifyPlayerDelay && !completelySilent) { sellallRateLimitExceededMsg( new SpigotCommandSender(p) ); -// Output.get().sendWarn(new SpigotPlayer(p), messages.getString(MessagesConfig.StringID.spigot_message_sellall_delay_wait)); } return false; } @@ -2331,7 +2354,6 @@ public boolean sellAllSell(Player p, if (!completelySilent){ sellallShopIsEmptyMsg( new SpigotCommandSender(p) ); -// Output.get().sendWarn(new SpigotPlayer(p), messages.getString(MessagesConfig.StringID.spigot_message_sellall_sell_empty)); } return false; } @@ -2353,7 +2375,7 @@ public boolean sellAllSell(Player p, //TODO inventory access: getHashMapOfPlayerInventories() && removeSellableItems(p, p.getInventory()); // double money = getSellMoney(p); - if (money != 0){ + if (money != 0) { if ( amounts != null ) { @@ -2393,12 +2415,13 @@ public boolean sellAllSell(Player p, } if (notifyPlayerEarningDelay && isAutoSellEarningNotificationDelayEnabled){ - if (!isPlayerWaitingAutoSellNotification(p)){ + if (!isPlayerWaitingAutoSellNotification(p)) { addToAutoSellNotificationDelay(p); } addDelayedEarningAutoSellNotification(p, money); - } else if (notifyPlayerEarned){ + } + else if (notifyPlayerEarned) { DecimalFormat fFmt = Prison.get().getDecimalFormat("#,##0.00"); String amt = fFmt.format( money ); @@ -2411,14 +2434,14 @@ public boolean sellAllSell(Player p, } } return true; - } else { - if (!completelySilent){ + } + else { + if (!completelySilent && notifyNothingToSell) { if (isSellAllSoundEnabled && playSoundOnSellAll) { p.playSound(p.getLocation(), sellAllSoundFail, 3, 1); } sellallYouHaveNothingToSellMsg( new SpigotCommandSender(p) ); -// Output.get().sendInfo(new SpigotPlayer(p), messages.getString(MessagesConfig.StringID.spigot_message_sellall_sell_nothing_sellable)); } return false; } From e8b58e38c386d29f1aa182ca717d1401a62b8381 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sun, 13 Aug 2023 00:14:22 -0400 Subject: [PATCH 067/151] auto features: setup a sellall function on PrisonMinesBlockBreakEvent so it can be easier to utilize from other functions. --- docs/changelog_v3.3.x.md | 3 + .../api/PrisonMinesBlockBreakEvent.java | 66 +++++++++++++++++++ .../spigot/game/SpigotCommandSender.java | 3 +- 3 files changed, 71 insertions(+), 1 deletion(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 280dab766..59338ac04 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -17,6 +17,9 @@ These change logs represent the work that has been going on within prison. # 3.3.0-alpha.15c 2023-08-13 +* **auto features: setup a sellall function on PrisonMinesBlockBreakEvent so it can be easier to utilize from other functions.** + + * **AutoFeatures SellAll: Added the ability to disable the "nothing to sell" message without effecting the other settings.** diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/api/PrisonMinesBlockBreakEvent.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/api/PrisonMinesBlockBreakEvent.java index 5a8b734bd..8c4bd727e 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/api/PrisonMinesBlockBreakEvent.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/api/PrisonMinesBlockBreakEvent.java @@ -1,5 +1,6 @@ package tech.mcprison.prison.spigot.api; +import java.text.DecimalFormat; import java.util.ArrayList; import java.util.List; import java.util.TreeMap; @@ -9,6 +10,7 @@ import org.bukkit.event.HandlerList; import org.bukkit.event.block.BlockBreakEvent; +import tech.mcprison.prison.Prison; import tech.mcprison.prison.internal.block.MineTargetPrisonBlock; import tech.mcprison.prison.internal.block.PrisonBlock.PrisonBlockType; import tech.mcprison.prison.mines.data.Mine; @@ -20,6 +22,8 @@ import tech.mcprison.prison.spigot.block.OnBlockBreakMines.MinesEventResults; import tech.mcprison.prison.spigot.compat.SpigotCompatibility; import tech.mcprison.prison.spigot.game.SpigotPlayer; +import tech.mcprison.prison.spigot.sellall.SellAllUtil; +import tech.mcprison.prison.spigot.utils.tasks.PlayerAutoRankupTask; /** *

This is an event that prison calls before processing the blocks that @@ -291,6 +295,68 @@ public TreeMap getTargetBlockCounts() { return results; } + + + /** + *

This will perform a Prison's sellall on a player's inventory. + * This tracks how many nanoseconds it took to run and will log this + * information if Prison is in debug mode. This info will be appended + * to the debug info for the block break handling. + *

+ * + * @param description + */ + public void performSellAllOnPlayerInventoryLogged( String description ) { + + debugInfo.append( performSellAllOnPlayerInventoryString(description) ); + +// final long nanoStart = System.nanoTime(); +// boolean success = SellAllUtil.get().sellAllSell( getPlayer(), +// false, false, false, true, true, false); +// final long nanoStop = System.nanoTime(); +// double milliTime = (nanoStop - nanoStart) / 1000000d; +// +// DecimalFormat dFmt = Prison.get().getDecimalFormat("#,##0.00"); +// debugInfo.append( "(" ) +// .append( description) +// .append( ": " + (success ? "success" : "failed")) +// .append( " ms: " + dFmt.format( milliTime ) + ") "); + + PlayerAutoRankupTask.autoSubmitPlayerRankupTask( getSpigotPlayer(), debugInfo ); + + } + public String performSellAllOnPlayerInventoryString( String description ) { + + final long nanoStart = System.nanoTime(); + + boolean isUsingSign = false; + boolean completelySilent = false; + boolean notifyPlayerEarned = false; + boolean notifyPlayerDelay = false; + boolean notifyPlayerEarningDelay = true; + boolean playSoundOnSellAll = false; + boolean notifyNothingToSell = false; + + boolean success = SellAllUtil.get().sellAllSell( getPlayer(), + isUsingSign, completelySilent, + notifyPlayerEarned, notifyPlayerDelay, + notifyPlayerEarningDelay, playSoundOnSellAll, + notifyNothingToSell, null ); + final long nanoStop = System.nanoTime(); + double milliTime = (nanoStop - nanoStart) / 1000000d; + + DecimalFormat dFmt = Prison.get().getDecimalFormat("#,##0.00"); + StringBuilder sb = new StringBuilder(); + + sb.append( "(" ) + .append( description) + .append( ": " + (success ? "success" : "failed")) + .append( " ms: " + dFmt.format( milliTime ) + ") "); + + return sb.toString(); + } + + public Mine getMine() { return mine; } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotCommandSender.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotCommandSender.java index f3f1ca8d6..8e4b0d890 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotCommandSender.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotCommandSender.java @@ -99,7 +99,8 @@ public void sendMessage(String[] messages) { } } - @Override public void sendRaw(String json) { + @Override + public void sendRaw(String json) { if (bukkitSender instanceof org.bukkit.entity.Player) { json = Text.translateAmpColorCodes(json); Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "tellraw " + bukkitSender.getName() + " " + json); From dfdf1042f7b96518a4e82d05449986dd61d409a5 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sun, 13 Aug 2023 00:19:05 -0400 Subject: [PATCH 068/151] AutoFeatures: Added the ability to force an inventory sellall at the end of handling a bukkit BlockBreakEvent. This was added to help cover situations where third party plugins are trying to add additional bonus drops to the players. --- docs/changelog_v3.3.x.md | 4 +++ .../autofeatures/AutoFeaturesFileConfig.java | 8 ++++++ .../events/AutoManagerBlockBreakEvents.java | 8 ++++++ .../spigot/block/OnBlockBreakEventCore.java | 25 ++++++++++--------- 4 files changed, 33 insertions(+), 12 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 59338ac04..d1f912783 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -17,6 +17,10 @@ These change logs represent the work that has been going on within prison. # 3.3.0-alpha.15c 2023-08-13 +* **AutoFeatures: Added the ability to force an inventory sellall at the end of handling a bukkit BlockBreakEvent.** +This was added to help cover situations where third party plugins are trying to add additional bonus drops to the players. + + * **auto features: setup a sellall function on PrisonMinesBlockBreakEvent so it can be easier to utilize from other functions.** diff --git a/prison-core/src/main/java/tech/mcprison/prison/autofeatures/AutoFeaturesFileConfig.java b/prison-core/src/main/java/tech/mcprison/prison/autofeatures/AutoFeaturesFileConfig.java index c4a8c4180..d9328a462 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/autofeatures/AutoFeaturesFileConfig.java +++ b/prison-core/src/main/java/tech/mcprison/prison/autofeatures/AutoFeaturesFileConfig.java @@ -197,6 +197,14 @@ public enum AutoFeatures { "applies if debug mode is turned off."), + isForceSellAllOnInventoryWhenBukkitBlockBreakEventFires(inventory, false), + isForceSellAllOnInventoryWhenBukkitBlockBreakEventFires__readme(inventory, + "AutoManager's autosell does not touch the player's inventory. So this feature " + + "will perform a sellall on the player's inventory at the end of handling " + + "the bukkkit's BlockBreakEvent. This will not apply to anyother event. " + + "This can be enabled without enabling the autosell."), + + // isAutoSellPerBlockBreakInlinedEnabled(general, false), isAutoSellIfInventoryIsFull(inventory, true), diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerBlockBreakEvents.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerBlockBreakEvents.java index 05f0474c9..d2c234d1d 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerBlockBreakEvents.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerBlockBreakEvents.java @@ -21,6 +21,7 @@ import tech.mcprison.prison.spigot.api.PrisonMinesBlockBreakEvent; import tech.mcprison.prison.spigot.autofeatures.AutoManagerFeatures; import tech.mcprison.prison.spigot.block.BlockBreakPriority; +import tech.mcprison.prison.spigot.game.SpigotPlayer; public class AutoManagerBlockBreakEvents @@ -465,6 +466,13 @@ else if ( cancelBy == EventListenerCancelBy.drops ) { } + if ( isBoolean( AutoFeatures.isForceSellAllOnInventoryWhenBukkitBlockBreakEventFires ) ) { + + pmEvent.getDebugInfo().append( Output.get().getColorCodeWarning()); + pmEvent.performSellAllOnPlayerInventoryLogged( "BlockBreakEvent sellall"); + pmEvent.getDebugInfo().append( Output.get().getColorCodeDebug()); + } + printDebugInfo( pmEvent, start ); } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/block/OnBlockBreakEventCore.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/block/OnBlockBreakEventCore.java index 124f0fdc8..d789561e8 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/block/OnBlockBreakEventCore.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/block/OnBlockBreakEventCore.java @@ -910,19 +910,20 @@ else if ( results && pmEvent.getBbPriority().isMonitor() && mine != null ) { isPlayerAutosellEnabled && pmEvent.getSpigotPlayer().isInventoryFull() ) { + pmEvent.performSellAllOnPlayerInventoryLogged("BLOCKEVENTS priority sellall"); - final long nanoStart = System.nanoTime(); - boolean success = SellAllUtil.get().sellAllSell( pmEvent.getPlayer(), - false, false, false, true, true, false); - final long nanoStop = System.nanoTime(); - double milliTime = (nanoStop - nanoStart) / 1000000d; - - DecimalFormat dFmt = Prison.get().getDecimalFormat("#,##0.00"); - debugInfo.append( "(autosell BLOCKEVENTS: " + (success ? "success" : "failed") + - " ms: " + dFmt.format( milliTime ) + ") "); - - PlayerAutoRankupTask.autoSubmitPlayerRankupTask( pmEvent.getSpigotPlayer(), debugInfo ); - +// final long nanoStart = System.nanoTime(); +// boolean success = SellAllUtil.get().sellAllSell( pmEvent.getPlayer(), +// false, false, false, true, true, false); +// final long nanoStop = System.nanoTime(); +// double milliTime = (nanoStop - nanoStart) / 1000000d; +// +// DecimalFormat dFmt = Prison.get().getDecimalFormat("#,##0.00"); +// debugInfo.append( "(autosell BLOCKEVENTS: " + (success ? "success" : "failed") + +// " ms: " + dFmt.format( milliTime ) + ") "); +// +// PlayerAutoRankupTask.autoSubmitPlayerRankupTask( pmEvent.getSpigotPlayer(), debugInfo ); +// } } From a68a46911771d06d9f67a77c5862897ede9c9154 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sun, 13 Aug 2023 00:25:19 -0400 Subject: [PATCH 069/151] AutoFeatures: Added the ability to force a delayed inventory sellall at the end of handling a bukkit BlockBreakEvent. This is in addition to the other instant sellall at the end of the bukkit BlockBreakEvent. This has the ability to set a delay in ticks before it is fired. If a task was submitted for a player, then future tasks cannot be submitted for that player until the submitted sellall task was finished running. This was added to help cover situations where third party plugins are trying to add additional bonus drops to the players, but after prison is done handling the events. --- docs/changelog_v3.3.x.md | 6 +++ .../autofeatures/AutoFeaturesFileConfig.java | 11 +++++ .../events/AutoManagerBlockBreakEvents.java | 43 ++++++++++++++++++- 3 files changed, 59 insertions(+), 1 deletion(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index d1f912783..90c0203f5 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -17,6 +17,12 @@ These change logs represent the work that has been going on within prison. # 3.3.0-alpha.15c 2023-08-13 +* **AutoFeatures: Added the ability to force a delayed inventory sellall at the end of handling a bukkit BlockBreakEvent. This is in addition to the other instant sellall at the end of the bukkit BlockBreakEvent.** +This has the ability to set a delay in ticks before it is fired. +If a task was submitted for a player, then future tasks cannot be submitted for that player until the submitted sellall task was finished running. +This was added to help cover situations where third party plugins are trying to add additional bonus drops to the players, but after prison is done handling the events. + + * **AutoFeatures: Added the ability to force an inventory sellall at the end of handling a bukkit BlockBreakEvent.** This was added to help cover situations where third party plugins are trying to add additional bonus drops to the players. diff --git a/prison-core/src/main/java/tech/mcprison/prison/autofeatures/AutoFeaturesFileConfig.java b/prison-core/src/main/java/tech/mcprison/prison/autofeatures/AutoFeaturesFileConfig.java index d9328a462..63d27f353 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/autofeatures/AutoFeaturesFileConfig.java +++ b/prison-core/src/main/java/tech/mcprison/prison/autofeatures/AutoFeaturesFileConfig.java @@ -205,6 +205,17 @@ public enum AutoFeatures { "This can be enabled without enabling the autosell."), + isEnabledDelayedSellAllOnInventoryWhenBukkitBlockBreakEventFires(inventory, false), + isEnabledDelayedSellAllOnInventoryDelayInTicks(inventory, 2), + isEnabledDelayedSellAllOnInventoryDelayInTicks__readme(inventory, + "This option adds a delay to a sellall event. The delay can be set to " + + "a range of 0 or more ticks, with 2 ticks being the default. When a " + + "player breaks a block through the BlockBreakEvent, if this is enabled, " + + "then a task will be submitted to perform a sellall transaction for " + + "the player. Only one task per player can be submitted at a time, so " + + "if the player is agressivly mining, they cannot queue up many sellalls."), + + // isAutoSellPerBlockBreakInlinedEnabled(general, false), isAutoSellIfInventoryIsFull(inventory, true), diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerBlockBreakEvents.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerBlockBreakEvents.java index d2c234d1d..dec8fbdb8 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerBlockBreakEvents.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerBlockBreakEvents.java @@ -1,5 +1,7 @@ package tech.mcprison.prison.spigot.autofeatures.events; +import java.util.TreeSet; + import org.bukkit.Bukkit; import org.bukkit.block.Block; import org.bukkit.entity.Player; @@ -12,6 +14,7 @@ import org.bukkit.inventory.ItemStack; import org.bukkit.plugin.EventExecutor; import org.bukkit.plugin.PluginManager; +import org.bukkit.scheduler.BukkitRunnable; import tech.mcprison.prison.autofeatures.AutoFeaturesFileConfig.AutoFeatures; import tech.mcprison.prison.autofeatures.AutoFeaturesWrapper; @@ -30,11 +33,19 @@ public class AutoManagerBlockBreakEvents { private BlockBreakPriority bbPriority; + + private TreeSet delayedSellallPlayers; + + public AutoManagerBlockBreakEvents() { super(); + + this.delayedSellallPlayers = new TreeSet<>(); } public AutoManagerBlockBreakEvents( BlockBreakPriority bbPriority ) { super(); + + this.delayedSellallPlayers = new TreeSet<>(); this.bbPriority = bbPriority; } @@ -473,6 +484,33 @@ else if ( cancelBy == EventListenerCancelBy.drops ) { pmEvent.getDebugInfo().append( Output.get().getColorCodeDebug()); } + if ( isBoolean( AutoFeatures.isEnabledDelayedSellAllOnInventoryWhenBukkitBlockBreakEventFires ) ) { + + if ( !getDelayedSellallPlayers().contains( pmEvent.getSpigotPlayer() ) ) { + + getDelayedSellallPlayers().add( pmEvent.getSpigotPlayer() ); + + int ticks = getInteger( AutoFeatures.isEnabledDelayedSellAllOnInventoryDelayInTicks ); + + pmEvent.getDebugInfo().append( Output.get().getColorCodeError()); + pmEvent.getDebugInfo().append( "(BlockBreakEvent delayed sellall submitted: no details available, see sellall debug info) " ); + pmEvent.getDebugInfo().append( Output.get().getColorCodeDebug()); + + final PrisonMinesBlockBreakEvent pmEventFinal = pmEvent; + + new BukkitRunnable() { + @Override + public void run() { + + String message = pmEventFinal.performSellAllOnPlayerInventoryString("delayed sellall"); + getDelayedSellallPlayers().remove( pmEventFinal.getSpigotPlayer() ); + + Output.get().logDebug(message); + } + }.runTaskLater( SpigotPrison.getInstance(), ticks ); + } + } + printDebugInfo( pmEvent, start ); } @@ -481,6 +519,9 @@ protected int checkBonusXp( Player player, Block block, ItemStack item ) { return bonusXp; } - + + public TreeSet getDelayedSellallPlayers() { + return delayedSellallPlayers; + } } From f18b5c3dac1ba4377ba04d58532ba31e9799092e Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sun, 13 Aug 2023 00:29:04 -0400 Subject: [PATCH 070/151] AutoFeatures XPrison event listener: Fixed a bug that was ignoring the first block in the exploded block list. --- docs/changelog_v3.3.x.md | 3 +++ .../events/AutoManagerXPrisonExplosionTriggerEvent.java | 2 +- .../events/AutoManagerXPrisonLayerTriggerEvent.java | 2 +- .../events/AutoManagerXPrisonNukeTriggerEvent.java | 2 +- 4 files changed, 6 insertions(+), 3 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 90c0203f5..5f98eb6c7 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -17,6 +17,9 @@ These change logs represent the work that has been going on within prison. # 3.3.0-alpha.15c 2023-08-13 +* **AutoFeatures XPrison event listener: Fixed a bug that was ignoring the first block in the exploded block list.** + + * **AutoFeatures: Added the ability to force a delayed inventory sellall at the end of handling a bukkit BlockBreakEvent. This is in addition to the other instant sellall at the end of the bukkit BlockBreakEvent.** This has the ability to set a delay in ticks before it is fired. If a task was submitted for a player, then future tasks cannot be submitted for that player until the submitted sellall task was finished running. diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerXPrisonExplosionTriggerEvent.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerXPrisonExplosionTriggerEvent.java index 63218cbf5..2fa73f1ee 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerXPrisonExplosionTriggerEvent.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerXPrisonExplosionTriggerEvent.java @@ -345,7 +345,7 @@ public void handleXPrisonExplosionTriggerEvent( ExplosionTriggerEvent e, BlockBr } - for ( int i = 1; i < e.getBlocksAffected().size(); i++ ) { + for ( int i = 0; i < e.getBlocksAffected().size(); i++ ) { pmEvent.getUnprocessedRawBlocks().add( e.getBlocksAffected().get( i ) ); } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerXPrisonLayerTriggerEvent.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerXPrisonLayerTriggerEvent.java index e64aa802d..49a292082 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerXPrisonLayerTriggerEvent.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerXPrisonLayerTriggerEvent.java @@ -345,7 +345,7 @@ public void handleXPrisonLayerTriggerEvent( LayerTriggerEvent e, BlockBreakPrior } - for ( int i = 1; i < e.getBlocksAffected().size(); i++ ) { + for ( int i = 0; i < e.getBlocksAffected().size(); i++ ) { pmEvent.getUnprocessedRawBlocks().add( e.getBlocksAffected().get( i ) ); } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerXPrisonNukeTriggerEvent.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerXPrisonNukeTriggerEvent.java index 80e60990a..6ce8ac71f 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerXPrisonNukeTriggerEvent.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerXPrisonNukeTriggerEvent.java @@ -345,7 +345,7 @@ public void handleXPrisonNukeTriggerEvent( NukeTriggerEvent e, BlockBreakPriorit } - for ( int i = 1; i < e.getBlocksAffected().size(); i++ ) { + for ( int i = 0; i < e.getBlocksAffected().size(); i++ ) { pmEvent.getUnprocessedRawBlocks().add( e.getBlocksAffected().get( i ) ); } From d7273aa81e0c23ef47415142056321ad40887336 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sun, 13 Aug 2023 22:41:57 -0400 Subject: [PATCH 071/151] AutoFeatures: Add comment on autosell by perms so it's clear what setting are needed. Also added a setting of 'false', in addition to 'disable', which disables the permission based autosell. --- docs/changelog_v3.3.x.md | 4 ++++ .../prison/autofeatures/AutoFeaturesFileConfig.java | 7 +++++++ .../prison/spigot/autofeatures/AutoManagerFeatures.java | 2 ++ .../prison/spigot/block/OnBlockBreakEventCore.java | 2 -- 4 files changed, 13 insertions(+), 2 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 5f98eb6c7..6ba8093f3 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -17,6 +17,10 @@ These change logs represent the work that has been going on within prison. # 3.3.0-alpha.15c 2023-08-13 +* **AutoFeatures: Add comment on autosell by perms so it's clear what setting are needed.** +Also added a setting of 'false', in addition to 'disable', which disables the permission based autosell. + + * **AutoFeatures XPrison event listener: Fixed a bug that was ignoring the first block in the exploded block list.** diff --git a/prison-core/src/main/java/tech/mcprison/prison/autofeatures/AutoFeaturesFileConfig.java b/prison-core/src/main/java/tech/mcprison/prison/autofeatures/AutoFeaturesFileConfig.java index 63d27f353..5ab5876ec 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/autofeatures/AutoFeaturesFileConfig.java +++ b/prison-core/src/main/java/tech/mcprison/prison/autofeatures/AutoFeaturesFileConfig.java @@ -184,7 +184,14 @@ public enum AutoFeatures { isAutoSellPerBlockBreakEnabled(inventory, false), + permissionAutoSellPerBlockBreakEnabled(inventory, "prison.automanager.autosell"), + permissionAutoSellPerBlockBreakEnabled__readme(inventory, + "AutoSell by permission can be disabled with the use of 'disable', " + + "or 'false', for the perm name. " + + "Players cannot use the autosell permission while OP'd."), + + permissionAutoSellPerBlockBreakEnabled__ReadMe(inventory, "If OP then you cannot use this permission node since it would always " + diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerFeatures.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerFeatures.java index 68d2e69e0..bce89bf69 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerFeatures.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerFeatures.java @@ -878,7 +878,9 @@ protected int autoPickup( PrisonMinesBlockBreakEvent pmEvent, boolean autoSellByPerm = isPlayerAutosellEnabled && !player.isOp() && + isBoolean(AutoFeatures.isAutoSellPerBlockBreakEnabled) && !"disable".equalsIgnoreCase( getMessage( AutoFeatures.permissionAutoSellPerBlockBreakEnabled ) ) && + !"false".equalsIgnoreCase( getMessage( AutoFeatures.permissionAutoSellPerBlockBreakEnabled ) ) && player.hasPermission( getMessage( AutoFeatures.permissionAutoSellPerBlockBreakEnabled ) ); // Try to autosell if enabled in any of the following ways: diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/block/OnBlockBreakEventCore.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/block/OnBlockBreakEventCore.java index d789561e8..11d927ba4 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/block/OnBlockBreakEventCore.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/block/OnBlockBreakEventCore.java @@ -1,6 +1,5 @@ package tech.mcprison.prison.spigot.block; -import java.text.DecimalFormat; import java.util.ArrayList; import java.util.List; import java.util.Random; @@ -36,7 +35,6 @@ import tech.mcprison.prison.spigot.game.SpigotPlayer; import tech.mcprison.prison.spigot.sellall.SellAllUtil; import tech.mcprison.prison.spigot.utils.BlockUtils; -import tech.mcprison.prison.spigot.utils.tasks.PlayerAutoRankupTask; import tech.mcprison.prison.util.Text; public abstract class OnBlockBreakEventCore From c207b7483c0364a31ebdfa7f40460d3cf1e3b182 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Wed, 16 Aug 2023 01:05:37 -0400 Subject: [PATCH 072/151] AutoFeatures: Expand the number of features being reported to bstats. Removed a duplicate comment in the autoFeatures config file. --- docs/changelog_v3.3.x.md | 6 +- .../autofeatures/AutoFeaturesFileConfig.java | 57 ++++++++++++++++++- 2 files changed, 59 insertions(+), 4 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 6ba8093f3..550f169b7 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -14,7 +14,11 @@ These change logs represent the work that has been going on within prison. -# 3.3.0-alpha.15c 2023-08-13 +# 3.3.0-alpha.15c 2023-08-16 + + +* **AutoFeatures: Expand the number of features being reported to bstats.** +Removed a duplicate comment in the autoFeatures config file. * **AutoFeatures: Add comment on autosell by perms so it's clear what setting are needed.** diff --git a/prison-core/src/main/java/tech/mcprison/prison/autofeatures/AutoFeaturesFileConfig.java b/prison-core/src/main/java/tech/mcprison/prison/autofeatures/AutoFeaturesFileConfig.java index 5ab5876ec..c11e20616 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/autofeatures/AutoFeaturesFileConfig.java +++ b/prison-core/src/main/java/tech/mcprison/prison/autofeatures/AutoFeaturesFileConfig.java @@ -193,9 +193,9 @@ public enum AutoFeatures { - permissionAutoSellPerBlockBreakEnabled__ReadMe(inventory, - "If OP then you cannot use this permission node since it would always " + - "be enabled. Using a value of 'disable' will turn it off for everyone."), +// permissionAutoSellPerBlockBreakEnabled__ReadMe(inventory, +// "If OP then you cannot use this permission node since it would always " + +// "be enabled. Using a value of 'disable' will turn it off for everyone."), // isAutoSellLeftoversForceDebugLogging(inventory, true), isAutoSellLeftoversForceDebugLogging__ReadMe(inventory, @@ -1071,6 +1071,7 @@ public TreeMap getBstatsDetails() { bStatsDetailPriority( AutoFeatures.blockBreakEventPriority, tm ); bStatsDetailPriority( AutoFeatures.ProcessPrisons_ExplosiveBlockBreakEventsPriority, tm ); + bStatsDetailPriority( AutoFeatures.TokenEnchantBlockExplodeEventPriority, tm ); bStatsDetailPriority( AutoFeatures.CrazyEnchantsBlastUseEventPriority, tm ); bStatsDetailPriority( AutoFeatures.RevEnchantsExplosiveEventPriority, tm ); @@ -1079,15 +1080,44 @@ public TreeMap getBstatsDetails() { bStatsDetailPriority( AutoFeatures.ZenchantmentsBlockShredEventPriority, tm ); bStatsDetailPriority( AutoFeatures.PrisonEnchantsExplosiveEventPriority, tm ); + bStatsDetailPriority( AutoFeatures.XPrisonExplosionTriggerEventPriority, tm ); + bStatsDetailPriority( AutoFeatures.XPrisonLayerTriggerEventPriority, tm ); + bStatsDetailPriority( AutoFeatures.XPrisonNukeTriggerEventPriority, tm ); + + bStatsDetailBoolean( AutoFeatures.isCalculateFoodExhustion, tm ); + bStatsDetailBoolean( AutoFeatures.isCalculateSilkEnabled, tm ); + bStatsDetailBoolean( AutoFeatures.isCalculateDropAdditionsEnabled, tm ); + bStatsDetailBoolean( AutoFeatures.isCalculateXPEnabled, tm ); bStatsDetailBoolean( AutoFeatures.givePlayerXPAsOrbDrops, tm ); + bStatsDetailBoolean( AutoFeatures.ifBlockIsAlreadyCountedThenCancelEvent, tm ); + bStatsDetailBoolean( AutoFeatures.processMonitorEventsOnlyIfPrimaryBlockIsAIR, tm ); + bStatsDetailBoolean( AutoFeatures.isMinecraftStatsReportingEnabled, tm ); + bStatsDetailBoolean( AutoFeatures.eventPriorityACCESSFailureTPToCurrentMine, tm ); + + + + bStatsDetailBoolean( AutoFeatures.isAutoSellPerBlockBreakEnabled, tm ); + bStatsDetailBoolean( AutoFeatures.permissionAutoSellPerBlockBreakEnabled, tm ); + + bStatsDetailPriority( AutoFeatures.isAutoSellLeftoversForceDebugLogging, tm ); + bStatsDetailPriority( AutoFeatures.isForceSellAllOnInventoryWhenBukkitBlockBreakEventFires, tm ); + + bStatsDetailPriority( AutoFeatures.isEnabledDelayedSellAllOnInventoryWhenBukkitBlockBreakEventFires, tm ); + bStatsDetailPriority( AutoFeatures.isEnabledDelayedSellAllOnInventoryDelayInTicks, tm ); + bStatsDetailBoolean( AutoFeatures.isAutoSellIfInventoryIsFull, tm ); + bStatsDetailBoolean( AutoFeatures.isAutoSellIfInventoryIsFullForBLOCKEVENTSPriority, tm ); bStatsDetailBoolean( AutoFeatures.dropItemsIfInventoryIsFull, tm ); + bStatsDetailBoolean( AutoFeatures.actionBarMessageIfInventoryIsFull, tm ); + + + bStatsDetailBoolean( AutoFeatures.isAutoFeaturesEnabled, tm ); if ( isFeatureBoolean( AutoFeatures.isAutoFeaturesEnabled ) ) { @@ -1107,11 +1137,32 @@ public TreeMap getBstatsDetails() { bStatsDetailBoolean( AutoFeatures.tokensEnabled, tm ); + bStatsDetailBoolean( AutoFeatures.tokensBlocksPerToken, tm ); + + + bStatsDetailBoolean( AutoFeatures.isLoreEnabled, tm ); + if ( isFeatureBoolean( AutoFeatures.isLoreEnabled )) { + + bStatsDetailBoolean( AutoFeatures.loreTrackBlockBreakCount, tm ); + bStatsDetailBoolean( AutoFeatures.loreDurabiltyResistance, tm ); + } + + + bStatsDetailBoolean( AutoFeatures.isCalculateDurabilityEnabled, tm ); bStatsDetailBoolean( AutoFeatures.isPreventToolBreakage, tm ); + bStatsDetailBoolean( AutoFeatures.preventToolBreakageThreshold, tm ); + + + bStatsDetailBoolean( AutoFeatures.isCalculateFortuneEnabled, tm ); + bStatsDetailBoolean( AutoFeatures.fortuneMultiplierGlobal, tm ); + bStatsDetailBoolean( AutoFeatures.fortuneMultiplierMax, tm ); + bStatsDetailBoolean( AutoFeatures.fortuneBukkitDropsMultiplier, tm ); + bStatsDetailBoolean( AutoFeatures.isExtendBukkitFortuneCalculationsEnabled, tm ); + bStatsDetailBoolean( AutoFeatures.isCalculateAltFortuneEnabled, tm ); bStatsDetailBoolean( AutoFeatures.isCalculateAltFortuneOnAllBlocksEnabled, tm ); From b3f62729c132bae70c8d06c8b0fea496ed232ddd Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Wed, 16 Aug 2023 01:10:25 -0400 Subject: [PATCH 073/151] BlockBreak sync task: Found a possible cause of jitters, or visual appearance of lag. Basically, need to check the block to ensure it's not already AIR before setting it to AIR. This could happen if there is a heavy load on the server from other plugins, or from bukkit itself, and bukkit naturally breaks the block before prison's sync task can get to it. Prison submits the sync task to run "next" in the future, but if there are other tasks trying to run, and if they cause a longer delay, then it can appear to be laggy. --- docs/changelog_v3.3.x.md | 5 +++++ .../autofeatures/AutoManagerBreakBlockTask.java | 15 +++++++++------ 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 550f169b7..5851d81c2 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -17,6 +17,11 @@ These change logs represent the work that has been going on within prison. # 3.3.0-alpha.15c 2023-08-16 +* **BlockBreak sync task: Found a possible cause of jitters, or visual appearance of lag.** +Basically, need to check the block to ensure it's not already AIR before setting it to AIR. This could happen if there is a heavy load on the server from other plugins, or from bukkit itself, and bukkit naturally breaks the block before prison's sync task can get to it. +Prison submits the sync task to run "next" in the future, but if there are other tasks trying to run, and if they cause a longer delay, then it can appear to be laggy. + + * **AutoFeatures: Expand the number of features being reported to bstats.** Removed a duplicate comment in the autoFeatures config file. diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerBreakBlockTask.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerBreakBlockTask.java index cf6ef2e0c..5da51a904 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerBreakBlockTask.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerBreakBlockTask.java @@ -76,13 +76,16 @@ public void run() { int count = 0; for ( SpigotBlock spigotBlock : blocks ) { - if ( count++ % 10 == 0 && mineStateMutexClone != null && - !mine.getMineStateMutex().isValidState( mineStateMutexClone ) ) { - return; + if ( spigotBlock != null && !spigotBlock.isEmpty() ) { + + if ( count++ % 10 == 0 && mineStateMutexClone != null && + !mine.getMineStateMutex().isValidState( mineStateMutexClone ) ) { + return; + } + + spigotBlock.setPrisonBlock( PrisonBlock.AIR ); + } - - spigotBlock.setPrisonBlock( PrisonBlock.AIR ); - } } } From 3e3cc619f590b79fb32061462592da1e3115f65b Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Wed, 16 Aug 2023 04:02:05 -0400 Subject: [PATCH 074/151] v3.3.0-alpha.15d 2023-08-16 --- docs/changelog_v3.3.x.md | 6 +++++- gradle.properties | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 5851d81c2..31a2007f2 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -14,7 +14,11 @@ These change logs represent the work that has been going on within prison. -# 3.3.0-alpha.15c 2023-08-16 +# 3.3.0-alpha.15d 2023-08-16 + + + +**v3.3.0-alpha.15d 2023-08-16** * **BlockBreak sync task: Found a possible cause of jitters, or visual appearance of lag.** diff --git a/gradle.properties b/gradle.properties index 3bf67908a..28286d517 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,7 +3,7 @@ ## # This is actually the "correct" place to define the version for the project. ## # Used within build.gradle with ${project.version}. ## # Can be overridden on the command line: gradle -Pversion=3.2.1-alpha.3 -version=3.3.0-alpha.15c +version=3.3.0-alpha.15d From 335bc7e479fef2c4444ee537e53819d8104d8d78 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Wed, 16 Aug 2023 04:05:30 -0400 Subject: [PATCH 075/151] Mine reset time: Found a conflict with the setting '*disable*' being ignored. It's been fixed. --- docs/changelog_v3.3.x.md | 4 ++++ .../tech/mcprison/prison/mines/commands/MinesCommands.java | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 31a2007f2..167bdf41f 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -21,6 +21,10 @@ These change logs represent the work that has been going on within prison. **v3.3.0-alpha.15d 2023-08-16** +* **Mine reset time: Found a conflict with the setting '*disable*' being ignored.** +It's been fixed. + + * **BlockBreak sync task: Found a possible cause of jitters, or visual appearance of lag.** Basically, need to check the block to ensure it's not already AIR before setting it to AIR. This could happen if there is a heavy load on the server from other plugins, or from bukkit itself, and bukkit naturally breaks the block before prison's sync task can get to it. Prison submits the sync task to run "next" in the future, but if there are other tasks trying to run, and if they cause a longer delay, then it can appear to be laggy. diff --git a/prison-mines/src/main/java/tech/mcprison/prison/mines/commands/MinesCommands.java b/prison-mines/src/main/java/tech/mcprison/prison/mines/commands/MinesCommands.java index 5ab0f576a..3456bc179 100644 --- a/prison-mines/src/main/java/tech/mcprison/prison/mines/commands/MinesCommands.java +++ b/prison-mines/src/main/java/tech/mcprison/prison/mines/commands/MinesCommands.java @@ -1885,7 +1885,7 @@ public void skipResetCommand(CommandSender sender, @Command(identifier = "mines set resetTime", permissions = "mines.set", description = "Set a mine's auto reset time as expressed in seconds.") public void resetTimeCommand(CommandSender sender, - @Arg(name = "mineName", description = "The name of the mine to edit.") String mineName, + @Arg(name = "mineName", description = "The name of the mine to edit, or '*all' to apply to all mines.") String mineName, @Arg(name = "time", description = "Time in seconds for the mine to auto reset. " + "With a minimum value of "+ MineData.MINE_RESET__TIME_SEC__MINIMUM + " seconds. " + "Using '*disable*' will turn off the auto reset. Use of " @@ -1918,7 +1918,7 @@ else if ( "*default*".equalsIgnoreCase( time ) ) { return; } } - if ( resetTime < MineData.MINE_RESET__TIME_SEC__MINIMUM ) { + if ( !"*disable*".equalsIgnoreCase( time ) && resetTime < MineData.MINE_RESET__TIME_SEC__MINIMUM ) { Output.get().sendWarn( sender, "&7Invalid resetTime value for &b%s&7. Must be an integer value of &b%d&7 or greater. [&b%d&7]", mineName, MineData.MINE_RESET__TIME_SEC__MINIMUM, resetTime ); From 6d14f32d2dcee09c3a45ac277190b6443f872013 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Fri, 18 Aug 2023 17:48:56 -0400 Subject: [PATCH 076/151] Added a `/mines top` command, alias `/mtop`, which will tp a player to the spawn location of the current mine they are in. If they are not in a mine, then it will tp them to a mine tied to their current default rank. --- .../prison/mines/commands/MinesCommands.java | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/prison-mines/src/main/java/tech/mcprison/prison/mines/commands/MinesCommands.java b/prison-mines/src/main/java/tech/mcprison/prison/mines/commands/MinesCommands.java index 3456bc179..35512e819 100644 --- a/prison-mines/src/main/java/tech/mcprison/prison/mines/commands/MinesCommands.java +++ b/prison-mines/src/main/java/tech/mcprison/prison/mines/commands/MinesCommands.java @@ -3330,6 +3330,53 @@ else if ( playerAlt != null && !player.getName().equalsIgnoreCase( playerAlt.get } } + + + @Command(identifier = "mines top", + description = "TP to the top of the current mine. Will default to the mine's " + + "spawn location if set, but can specify the target [spawn, mine]. If not in a " + + "mine, then it will be the same as '/mtp' where it will take you to a mine that " + + "is linked to your current rank. This command has no options.", + aliases = "mtop", + altPermissions = {"access-by-rank", "mines.tp"}) + public void mineTpTop(CommandSender sender ) { + + + Player player = getPlayer( sender ); + //oboolean isOp = sender.isOp(); + + + if ( player == null || !player.isOnline() ) { + + teleportPlayerMustBeIngameMsg( sender ); + return; + } + + + PrisonMines pMines = PrisonMines.getInstance(); + + Mine mine = pMines.findMineLocationExact( player.getLocation() ); + + + if ( mine != null ) { + if ( mine.isVirtual() ) { + teleportCannotUseVirtualMinesMsg( sender ); + return; + } + else { + + mineTp( sender, mine.getName(), "", "spawn"); + } + } + else { + // Player is not in a mine, so issue `/mtp` command for them: + mineTp( sender, "", "", ""); + } + + + + } + private void teleportPlayer( Player player, Mine mine, String target ) { if ( Prison.get().getPlatform().getConfigBooleanFalse( "prison-mines.tp-warmup.enabled" ) ) { From b9396a83db85a51452c2610167c11289cb97e9af Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 19 Aug 2023 10:54:47 -0400 Subject: [PATCH 077/151] AutoManager: Added a new fortune type: percentGradient. This fortune calculation is an alternative to the extendedBukkit and altFortune calculations. This fortune calculation applies a linear distribution based upon the player's tool's fortune level versus the maxfortuneLevel and the maxBonusBlocks. --- docs/changelog_v3.3.x.md | 10 ++++- docs/prison_docs_311_guide_automanager.md | 39 ++++++++++++++++++ .../autofeatures/AutoFeaturesFileConfig.java | 33 +++++++++++++++ .../autofeatures/AutoManagerFeatures.java | 41 ++++++++++++++++++- 4 files changed, 121 insertions(+), 2 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 167bdf41f..b2dfd95f8 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -14,9 +14,17 @@ These change logs represent the work that has been going on within prison. -# 3.3.0-alpha.15d 2023-08-16 +# 3.3.0-alpha.15d 2023-08-18 +* **AutoManager: Added a new fortune type: percentGradient.** +This fortune calculation is an alternative to the extendedBukkit and altFortune calculations. +This fortune calculation applies a linear distribution based upon the player's tool's fortune level versus the maxfortuneLevel and the maxBonusBlocks. + + +* **Added a `/mines top` command, alias `/mtop`, which will tp a player to the spawn location of the current mine they are in. ** +If they are not in a mine, then it will tp them to a mine tied to their current default rank. + **v3.3.0-alpha.15d 2023-08-16** diff --git a/docs/prison_docs_311_guide_automanager.md b/docs/prison_docs_311_guide_automanager.md index 3cbe8227f..78c9e2404 100644 --- a/docs/prison_docs_311_guide_automanager.md +++ b/docs/prison_docs_311_guide_automanager.md @@ -466,6 +466,45 @@ Remember that the settings for `fortuneBukkitDropsMultiplier`, `fortuneMultiplie * Formula: raw_adjusted_drops x +**Prison's Percent Gradient Fortune Calculation** + +New as of v3.3.0-alpha.15e + +This is a new fortune calculation type, which defines a max fortune amount, and a max bonus payout that is possible. Then based upon the fortune level on the player's tool, it will payout a linear maximum amount, adjusted by a random range. + +To enable, you need to setup the following settings within the autoFeaturesConfig.yml file. If you just upgraded prison, restart prison, and the new settings will be injected in to the config file for you. Then modify those settings, and then use `/prison reload autoFeatures`. + +These settings must be set to these values to use this new fortune calculation: + +```yml + + fortuneFeature: + isCalculateFortuneEnabled: true + isExtendBukkitFortuneCalculationsEnabled: false + isCalculateAltFortuneEnabled: false + percentGradientFortune: + isPercentGradientFortuneEnabled: true + + percentGradientFortuneMaxFortuneLevel: 1000 + percentGradientFortuneMaxBonusBlocks: 200 + percentGradientFortuneMinPercentRandomness: 25.0 +``` + +The last three listed settings can be customized however you need them to be. + + +Percent Gradient Fortune is an alternative fortune calculation that will only be enabled if extendedBukkitFortune and altFortune is turned off. + +Percent Gradient Fortune will always drop a minimum of 1 block with fortune 0 and higher. The max it will ever drop, will be 1 + MaxBonusBlocks-amount. The calculation of the MaxBonusBlocks will be a random roll resulting in 0 bonus blocks, to the MaxBonusBlocks amount IF the player has the max fortune on their tool. + +For fortune amounts less than the maxFortuneLevel, it will be treated as a linear percentage gradient of the max amount. For example, MaxFortuneLevel= 1000, and MaxBonusBlocks= 200. Therefore if the player has a fortune 500, the max bonus they could get would be only 100 blocks, but could be as low as zero bonus blocks since it's a random roll on each calculation. If they have a fort 250, then it will be 25% of 200, or 50 blocks as a max bonus. + +For better control of the randomness applied to the bonus block calculations, the MinPercentRandomness sets the lowest range for the randomness. What this means, is for a maxFortuneLevel= 1000 and a maxBonusBlocks of= 200, and a tool with fort 500, the calcs would be for a bonus between '0' and (500 / 1000 * 200 =) 100 bonus blocks. But with the minPercentRandomness= 25, then the range would be '25%' to 100% of the 100 bonus blocks. The minePercentRandomness would ensure a higher payout of bonus blocks, without effecting the max payout. minPercentRandomness has a valid range of 0.0 (off) to 99.0 percent. + +No other fortune multipliers will apply to these calculations. + +The percentage gradient is a very controlled way of paying out fortune bonuses. +
diff --git a/prison-core/src/main/java/tech/mcprison/prison/autofeatures/AutoFeaturesFileConfig.java b/prison-core/src/main/java/tech/mcprison/prison/autofeatures/AutoFeaturesFileConfig.java index c11e20616..4e006aec4 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/autofeatures/AutoFeaturesFileConfig.java +++ b/prison-core/src/main/java/tech/mcprison/prison/autofeatures/AutoFeaturesFileConfig.java @@ -330,7 +330,40 @@ public enum AutoFeatures { isCalculateAltFortuneOnAllBlocksEnabled(fortuneFeature, false), + percentGradientFortune(fortuneFeature), + isPercentGradientFortuneEnabled(percentGradientFortune, false), + isPercentGradientFortuneEnabled__readme(percentGradientFortune, + "Percent Gradient Fortune is an alternative fortune calculation that " + + "will only be enabled if extendedBukkitFortune and altFortune is " + + "turned off. Percent Gradient Fortune will always drop a minimum of " + + "1 block with fortune 0 and higher. The max it will ever drop, will " + + "be 1 + MaxBonusBlocks amount. The calculation of the MaxBonusBlocks " + + "will be a random roll resulting in 0 bonus blocks, to the MaxBonusBlocks " + + "amount IF the player has the max fortune on their tool. For fortune " + + "ammounts less than the maxFortuneLevel, it will be treated as a " + + "linear percentage gradient of the max amount. " + + "For example, MaxFortuneLevel= 1000, and MaxBonusBlocks= 200. " + + "Therefore if the player has a fortune 500, the max bonus they could get would " + + "be only 100 blocks, but could be as low as zero bonus blocks since it's a random " + + "roll on each calculation. If they have a fort 250, then it will be 25% of 200, or 50 " + + "blocks as a max bonus. " + + "For better control of the randomness applied to the bonus block calculations, " + + "the MinPercentRandomness sets the lowest range for the randomness. What this means, " + + "is for a maxFortuneLevel= 1000 and a maxBonusBlocks of= 200, and a tool with " + + "fort 500, the calcs would be for a bonus between '0' and (500 / 1000 * 200 =) 100 " + + "bonus blocks. But with the minPercentRandomness= 25, then the range would be " + + "'25%' to 100% of the 100 bonus blocks. The minePercentRandomness would ensure a " + + "higher payout of bonus blocks, without effecting the max payout. " + + "minPercentRandomness has a valid range of 0.0 (off) to 99.0 percent. " + + "No other fortune multipliers will apply to these calculations. The percentage " + + "gradient is a very controlled way of paying out fortune bonuses."), + + percentGradientFortuneMaxFortuneLevel(percentGradientFortune, 1000 ), + percentGradientFortuneMaxBonusBlocks(percentGradientFortune, 200 ), + + percentGradientFortuneMinPercentRandomness(percentGradientFortune, 25.0 ), + pickupFeature(options), diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerFeatures.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerFeatures.java index bce89bf69..465f74939 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerFeatures.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerFeatures.java @@ -2684,7 +2684,46 @@ else if ( ); debugInfo.append( msg ); } - + + else if ( isBoolean( AutoFeatures.isPercentGradientFortuneEnabled ) ) { + + int bonusBlocks = 0; + + int maxFortune = getInteger( AutoFeatures.percentGradientFortuneMaxFortuneLevel ); + int maxBonusBlocks = getInteger( AutoFeatures.percentGradientFortuneMaxBonusBlocks ); + double minPctRnd = getDouble( AutoFeatures.percentGradientFortuneMinPercentRandomness ); + + if ( maxFortune > 0 && maxBonusBlocks > 1 ) { + + minPctRnd = + minPctRnd < 0.0 ? 0.0 : + minPctRnd > 100.00 ? 99.0 : minPctRnd; + + double random = ((1.0 - (minPctRnd / 100)) * getRandom().nextDouble()) + (minPctRnd / 100); + + int fortLevel = fortuneLevelOriginal > maxFortune ? maxFortune : fortuneLevelOriginal; + + bonusBlocks = ( fortLevel / maxFortune ) * maxBonusBlocks; + + bonusBlocks *= random; + } + + // The count has the final value so set it as the amount: + blocks.setAmount( 1 + bonusBlocks ); + + String msg = String.format( + "(gradientFortune blocks: 1 + bonusBlocks=%s == (fortLevel=%s / maxFortLevel=%s) * " + + "maxBonusBlocks=%s * rnd=%s [with minPctRnd=%s]) ", + iFmt.format( bonusBlocks ), + iFmt.format( fortuneLevelOriginal ), + iFmt.format( maxFortune ), + iFmt.format( maxBonusBlocks ), + dFmt.format( random ), + dFmt.format( minPctRnd ) + ); + + debugInfo.append( msg ); + } } } From c0e7ba831fc27d91f420b17628aa4d3bfd7b4e12 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sun, 20 Aug 2023 20:36:02 -0400 Subject: [PATCH 078/151] AutoFeatures: Updated the gradient fortune to fix a problem with not setting the bonus block counts correctly. --- docs/changelog_v3.3.x.md | 7 ++++- .../autofeatures/AutoManagerFeatures.java | 28 ++++++++++--------- 2 files changed, 21 insertions(+), 14 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index b2dfd95f8..f5f2b4b25 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -14,7 +14,12 @@ These change logs represent the work that has been going on within prison. -# 3.3.0-alpha.15d 2023-08-18 +# 3.3.0-alpha.15d 2023-08-20 + + + + +* **AutoFeatures: Updated the gradient fortune to fix a problem with not setting the bonus block counts correctly.** * **AutoManager: Added a new fortune type: percentGradient.** diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerFeatures.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerFeatures.java index 465f74939..c50734da9 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerFeatures.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerFeatures.java @@ -372,15 +372,15 @@ protected boolean hasFortune(SpigotItemStack itemInHand){ return results; } - protected short getFortune(SpigotItemStack itemInHand, StringBuilder debugInfo ){ - short fortLevel = (short) 0; + protected int getFortune(SpigotItemStack itemInHand, StringBuilder debugInfo ){ + int fortLevel = 0; try { if ( itemInHand != null && itemInHand.getBukkitStack() != null && itemInHand.getBukkitStack().containsEnchantment( Enchantment.LOOT_BONUS_BLOCKS ) && itemInHand.getBukkitStack().getEnchantments() != null ) { - fortLevel = (short) itemInHand.getBukkitStack().getEnchantmentLevel(Enchantment.LOOT_BONUS_BLOCKS); + fortLevel = itemInHand.getBukkitStack().getEnchantmentLevel(Enchantment.LOOT_BONUS_BLOCKS); } } catch ( NullPointerException e ) { @@ -388,14 +388,14 @@ protected short getFortune(SpigotItemStack itemInHand, StringBuilder debugInfo ) // It throws this exception: Caused by: java.lang.NullPointerException: null key in entry: null=5 } - short results = (short) fortLevel; + int results = fortLevel; // DecimalFormat dFmt = new DecimalFormat( "#,##0.0000" ); DecimalFormat iFmt = new DecimalFormat( "#,##0" ); int maxFortuneLevel = getInteger( AutoFeatures.fortuneMultiplierMax ); String maxFort = ""; if ( maxFortuneLevel > 0 && fortLevel > maxFortuneLevel ) { - results = (short) maxFortuneLevel; + results = maxFortuneLevel; maxFort = String.format(" max=%s result=%s", iFmt.format( maxFortuneLevel ), iFmt.format( results )); @@ -794,7 +794,7 @@ protected int autoPickup( PrisonMinesBlockBreakEvent pmEvent, // Add fortune to the items in the inventory if ( isBoolean( AutoFeatures.isCalculateFortuneEnabled ) ) { sb.setLength(0); - short fortuneLevel = getFortune(itemInHand, debugInfo ); + int fortuneLevel = getFortune(itemInHand, debugInfo ); // debugInfo.append( "(calculateFortune: fort " + fortuneLevel + ")" ); @@ -1093,7 +1093,7 @@ public int calculateNormalDrop( PrisonMinesBlockBreakEvent pmEvent ) { // Need better drop calculation that is not using the getDrops function. - short fortuneLevel = getFortune( pmEvent.getItemInHand(), pmEvent.getDebugInfo() ); + int fortuneLevel = getFortune( pmEvent.getItemInHand(), pmEvent.getDebugInfo() ); // calculateSilkTouch( pmEvent.getItemInHand(), drops ); @@ -2688,24 +2688,26 @@ else if ( else if ( isBoolean( AutoFeatures.isPercentGradientFortuneEnabled ) ) { int bonusBlocks = 0; - + double rnd = 1.0; + int maxFortune = getInteger( AutoFeatures.percentGradientFortuneMaxFortuneLevel ); int maxBonusBlocks = getInteger( AutoFeatures.percentGradientFortuneMaxBonusBlocks ); double minPctRnd = getDouble( AutoFeatures.percentGradientFortuneMinPercentRandomness ); + int fortLevel = fortuneLevelOriginal > maxFortune ? maxFortune : fortuneLevelOriginal; + if ( maxFortune > 0 && maxBonusBlocks > 1 ) { minPctRnd = minPctRnd < 0.0 ? 0.0 : minPctRnd > 100.00 ? 99.0 : minPctRnd; - double random = ((1.0 - (minPctRnd / 100)) * getRandom().nextDouble()) + (minPctRnd / 100); + rnd = ((1.0 - (minPctRnd / 100)) * getRandom().nextDouble()) + (minPctRnd / 100); - int fortLevel = fortuneLevelOriginal > maxFortune ? maxFortune : fortuneLevelOriginal; bonusBlocks = ( fortLevel / maxFortune ) * maxBonusBlocks; - bonusBlocks *= random; + bonusBlocks *= rnd; } // The count has the final value so set it as the amount: @@ -2715,10 +2717,10 @@ else if ( isBoolean( AutoFeatures.isPercentGradientFortuneEnabled ) ) { "(gradientFortune blocks: 1 + bonusBlocks=%s == (fortLevel=%s / maxFortLevel=%s) * " + "maxBonusBlocks=%s * rnd=%s [with minPctRnd=%s]) ", iFmt.format( bonusBlocks ), - iFmt.format( fortuneLevelOriginal ), + iFmt.format( fortLevel ), iFmt.format( maxFortune ), iFmt.format( maxBonusBlocks ), - dFmt.format( random ), + dFmt.format( rnd ), dFmt.format( minPctRnd ) ); From 295670d0b247a7ccaf59f4ed5672e52506967848 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sun, 20 Aug 2023 20:37:59 -0400 Subject: [PATCH 079/151] AutoFeatures: Added a debug statement when player autosell has been toggled off by the player, since it may look as if autosell is not working correctly. Wrapped the notice in a WARNING color code so it stands out in the console with it being red. --- docs/changelog_v3.3.x.md | 2 ++ .../spigot/autofeatures/AutoManagerFeatures.java | 11 +++++++++++ 2 files changed, 13 insertions(+) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index f5f2b4b25..cef32b0c0 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -17,6 +17,8 @@ These change logs represent the work that has been going on within prison. # 3.3.0-alpha.15d 2023-08-20 +* **AutoFeatures: Added a debug statement when player autosell has been toggled off by the player, since it may look as if autosell is not working correctly.** +Wrapped the notice in a WARNING color code so it stands out in the console with it being red. * **AutoFeatures: Updated the gradient fortune to fix a problem with not setting the bonus block counts correctly.** diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerFeatures.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerFeatures.java index c50734da9..1bc8fbe6b 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerFeatures.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerFeatures.java @@ -855,6 +855,17 @@ protected int autoPickup( PrisonMinesBlockBreakEvent pmEvent, boolean isSellallEnabled = SellAllUtil.get() != null && SpigotPrison.getInstance().isSellAllEnabled(); + + boolean isPlayerAutoSellTurnedOff = SellAllUtil.get().isAutoSellPerUserToggleable && + !SellAllUtil.get().isSellallPlayerUserToggleEnabled( + pmEvent.getSpigotPlayer().getWrapper() ); + + if ( isPlayerAutoSellTurnedOff ) { + debugInfo.append( Output.get().getColorCodeWarning() ); + debugInfo.append( "(Player toggled off autosell) " ); + debugInfo.append( Output.get().getColorCodeDebug() ); + } + // This will return true (allow autosell) unless players can toggle autosell and they turned it off: // This is to be used with other auto sell setting, but never on it's own: boolean isPlayerAutosellEnabled = From 14a466b2416c477a0cf4a66c206ceeb5ed14274d Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sun, 20 Aug 2023 20:39:41 -0400 Subject: [PATCH 080/151] AutoFeatures: New option to use TokenEnchant to get the enchantment level through their API instead of using the bukkit functions to get the fortune. --- docs/changelog_v3.3.x.md | 3 +++ .../autofeatures/AutoFeaturesFileConfig.java | 2 ++ .../autofeatures/AutoManagerFeatures.java | 23 ++++++++++++++++++- 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index cef32b0c0..04f8cfcb3 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -17,6 +17,9 @@ These change logs represent the work that has been going on within prison. # 3.3.0-alpha.15d 2023-08-20 +* **AutoFeatures: New option to use TokenEnchant to get the enchantment level through their API instead of using the bukkit functions to get the fortune.** + + * **AutoFeatures: Added a debug statement when player autosell has been toggled off by the player, since it may look as if autosell is not working correctly.** Wrapped the notice in a WARNING color code so it stands out in the console with it being red. diff --git a/prison-core/src/main/java/tech/mcprison/prison/autofeatures/AutoFeaturesFileConfig.java b/prison-core/src/main/java/tech/mcprison/prison/autofeatures/AutoFeaturesFileConfig.java index 4e006aec4..1726b3344 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/autofeatures/AutoFeaturesFileConfig.java +++ b/prison-core/src/main/java/tech/mcprison/prison/autofeatures/AutoFeaturesFileConfig.java @@ -310,6 +310,8 @@ public enum AutoFeatures { isCalculateFortuneEnabled(fortuneFeature, true), + isUseTokenEnchantsFortuneLevel(fortuneFeature, false ), + fortuneMultiplierGlobal(fortuneFeature, 1.0 ), fortuneMultiplierMax(fortuneFeature, 0 ), diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerFeatures.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerFeatures.java index 1bc8fbe6b..9b7bcde9d 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerFeatures.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerFeatures.java @@ -23,6 +23,7 @@ import org.bukkit.inventory.meta.ItemMeta; import com.cryptomorin.xseries.XMaterial; +import com.vk2gpz.tokenenchant.api.TokenEnchantAPI; import tech.mcprison.prison.Prison; import tech.mcprison.prison.autofeatures.AutoFeaturesFileConfig.AutoFeatures; @@ -374,9 +375,29 @@ protected boolean hasFortune(SpigotItemStack itemInHand){ protected int getFortune(SpigotItemStack itemInHand, StringBuilder debugInfo ){ int fortLevel = 0; + boolean usedTEFortune = false; + + if ( isBoolean( AutoFeatures.isUseTokenEnchantsFortuneLevel ) && + itemInHand != null && + itemInHand.getBukkitStack() != null ) { + + try { + if ( TokenEnchantAPI.getInstance() != null ) { + + fortLevel = TokenEnchantAPI.getInstance().getEnchantments( itemInHand.getBukkitStack() ) + .get( TokenEnchantAPI.getInstance().getEnchantment("Fortune")); + + usedTEFortune = true; + } + } + catch ( Exception e ) { + // ignore: could not use TE. + } + } try { - if ( itemInHand != null && + if ( !usedTEFortune && + itemInHand != null && itemInHand.getBukkitStack() != null && itemInHand.getBukkitStack().containsEnchantment( Enchantment.LOOT_BONUS_BLOCKS ) && itemInHand.getBukkitStack().getEnchantments() != null ) { From 8afb949b8d2e635403a200995daeee7070d027d7 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sun, 20 Aug 2023 22:45:58 -0400 Subject: [PATCH 081/151] Sellall: Fixed a bug with spigot 1.8.8 where bricks were not able to be sold correctly. The issue is with XBlock not correctly mapping brick and bricks to the correct bukkit 1.8 materials. It may be close, or accurate, but when converting to a bukkit item stack, it fails to map back to the same objects. Sellall was not using the prison compatibility classes, and those classes for 1.8 had to be updated too. --- docs/changelog_v3.3.x.md | 5 +++++ .../main/java/tech/mcprison/prison/spigot/SpigotUtil.java | 4 +++- .../tech/mcprison/prison/spigot/compat/Spigot18Blocks.java | 4 ++++ 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 04f8cfcb3..1557f4497 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -17,6 +17,11 @@ These change logs represent the work that has been going on within prison. # 3.3.0-alpha.15d 2023-08-20 +* **Sellall: Fixed a bug with spigot 1.8.8 where bricks were not able to be sold correctly.** +The issue is with XBlock not correctly mapping brick and bricks to the correct bukkit 1.8 materials. It may be close, or accurate, but when converting to a bukkit item stack, it fails to map back to the same objects. +Sellall was not using the prison compatibility classes, and those classes for 1.8 had to be updated too. + + * **AutoFeatures: New option to use TokenEnchant to get the enchantment level through their API instead of using the bukkit functions to get the fortune.** diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/SpigotUtil.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/SpigotUtil.java index e8fe0f841..c37f9f0c3 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/SpigotUtil.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/SpigotUtil.java @@ -99,7 +99,9 @@ public static XMaterial getXMaterial( String materialName ) { public static XMaterial getXMaterial( PrisonBlock prisonBlock ) { - XMaterial xMat = getXMaterial( prisonBlock.getBlockName()); + XMaterial xMat = SpigotCompatibility.getInstance().getXMaterial(prisonBlock); + +// XMaterial xMat = getXMaterial( prisonBlock.getBlockName()); return xMat; } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot18Blocks.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot18Blocks.java index 96892420a..2220155fe 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot18Blocks.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot18Blocks.java @@ -284,6 +284,10 @@ else if ( results == XMaterial.BRICK && prisonBlock.getBlockName().equalsIgnoreCase( "bricks" ) ) { results = XMaterial.BRICKS; } + else if ( results == XMaterial.BRICK && + prisonBlock.getBlockName().equalsIgnoreCase( "brick" ) ) { + results = XMaterial.BRICKS; + } putCachedXMaterial( prisonBlock, results ); } From ae232c94df41a36913fa8fd96a1b6991ab30c08b Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Thu, 24 Aug 2023 20:06:57 -0400 Subject: [PATCH 082/151] Slime-fun: Moved a lot of the settings for it to the config.yml file instead of hard coding them. Now the messages can be turned off, and the boosters can now be added to, and changed. --- docs/changelog_v3.3.x.md | 6 +- .../mcprison/prison/spigot/SpigotPrison.java | 5 +- .../spigot/slime/SlimeBlockFunEventData.java | 80 +++++++---- .../slime/SlimeBlockFunEventListener.java | 125 ++++++++++++++---- prison-spigot/src/main/resources/config.yml | 21 ++- 5 files changed, 183 insertions(+), 54 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 1557f4497..4d05e7920 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -14,7 +14,11 @@ These change logs represent the work that has been going on within prison. -# 3.3.0-alpha.15d 2023-08-20 +# 3.3.0-alpha.15d 2023-08-24 + + +* **Slime-fun: Moved a lot of the settings for it to the config.yml file instead of hard coding them.** +Now the messages can be turned off, and the boosters can now be added to, and changed. * **Sellall: Fixed a bug with spigot 1.8.8 where bricks were not able to be sold correctly.** diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/SpigotPrison.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/SpigotPrison.java index 189db7af7..b2a96010d 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/SpigotPrison.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/SpigotPrison.java @@ -311,7 +311,10 @@ public void onEnableStartup() { Bukkit.getPluginManager().registerEvents(new ListenersPrisonManager(),this); - if ( getConfig().getBoolean( "slime-fun" ) ) { + boolean slimeFunEnabled1 = SpigotPrison.getInstance().getConfig().getBoolean("slime-fun"); + boolean slimeFunEnabled2 = SpigotPrison.getInstance().getConfig().getBoolean("slime-fun.enabled"); + + if ( slimeFunEnabled1 || slimeFunEnabled2 ) { Bukkit.getPluginManager().registerEvents(new SlimeBlockFunEventListener(), this); } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/slime/SlimeBlockFunEventData.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/slime/SlimeBlockFunEventData.java index 39a9a92b9..deb6b8661 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/slime/SlimeBlockFunEventData.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/slime/SlimeBlockFunEventData.java @@ -5,6 +5,7 @@ import org.bukkit.entity.Player; import tech.mcprison.prison.Prison; +import tech.mcprison.prison.spigot.SpigotPrison; import tech.mcprison.prison.util.Text; public class SlimeBlockFunEventData { @@ -24,10 +25,15 @@ public class SlimeBlockFunEventData { private double recordBoost = 0.0; private double recordVelocity = 0.0; + private boolean displayMessages = false; + + private final int worldHeight; + + private DecimalFormat sFmt = Prison.get().getDecimalFormat("#,##0.0"); private DecimalFormat dFmt = Prison.get().getDecimalFormat("#,##0.00"); - public SlimeBlockFunEventData( Long playerUUIDLSB, double y ) { + public SlimeBlockFunEventData( Long playerUUIDLSB, double y, int worldHeight ) { super(); this.playerUUIDLSB = playerUUIDLSB; @@ -38,6 +44,11 @@ public SlimeBlockFunEventData( Long playerUUIDLSB, double y ) { this.jumping = false; this.recordHeight = 0.0; this.recordY = 0.0; + + this.worldHeight = worldHeight; + + this.displayMessages = SpigotPrison.getInstance().getConfig() + .getBoolean("slime-fun.display-messages", true); } public void addJumpEvent( double y, double boost, double velocityY ) { @@ -68,11 +79,16 @@ public void inAir( double currentY, Player player ) { } else if ( currentY < getMaxY() ) { - if ( currentY >= 255 ) { - player.sendMessage( "SlimeFun: You jumped out of the world! " + - " y= " + dFmt.format( currentY )); + if ( isDisplayMessages() ) { + + if ( currentY >= getWorldHeight() ) { +// if ( currentY >= 255 ) { + player.sendMessage( "SlimeFun: You jumped out of the world! " + + " y= " + dFmt.format( currentY )); + } + } - + // Just starting to go back down!! // Stop recording the jump: atTopOfJump( player ); @@ -102,26 +118,29 @@ private void atTopOfJump( Player player ) setRecordVelocity( getVelocityY() ); } - String message1 = Text.translateAmpColorCodes( - String.format("&a%s &3Height: &7%s &a%s &3maxY: &7%s &a%s", - (recY || recH || recB || recV ? "&6.-=New=-." : "__Slime__"), - sFmt.format(height), - (recH ? "&6" : "" ) + sFmt.format( getRecordHeight() ), - sFmt.format(getMaxY()), - (recY ? "&6" : "" ) + sFmt.format( getRecordY()) - )); - - String message2 = Text.translateAmpColorCodes( - String.format("&a%s &3Boost: &7%s &b%s &a%s &3Velocity: &7%s &a%s", - (recY || recH || recB || recV ? "&6-Record!-" : "__Fun!!__"), - - dFmt.format(getBoost()), Integer.toString( getBoostCount()), - (recB ? "&6" : "" ) + dFmt.format( getRecordBoost() ), - dFmt.format(getVelocityY()), - (recV ? "&6" : "" ) + dFmt.format(getRecordVelocity()) - )); - player.sendMessage( message1 ); - player.sendMessage( message2 ); + if ( isDisplayMessages() ) { + + String message1 = Text.translateAmpColorCodes( + String.format("&a%s &3Height: &7%s &a%s &3maxY: &7%s &a%s", + (recY || recH || recB || recV ? "&6.-=New=-." : "__Slime__"), + sFmt.format(height), + (recH ? "&6" : "" ) + sFmt.format( getRecordHeight() ), + sFmt.format(getMaxY()), + (recY ? "&6" : "" ) + sFmt.format( getRecordY()) + )); + + String message2 = Text.translateAmpColorCodes( + String.format("&a%s &3Boost: &7%s &b%s &a%s &3Velocity: &7%s &a%s", + (recY || recH || recB || recV ? "&6-Record!-" : "__Fun!!__"), + + dFmt.format(getBoost()), Integer.toString( getBoostCount()), + (recB ? "&6" : "" ) + dFmt.format( getRecordBoost() ), + dFmt.format(getVelocityY()), + (recV ? "&6" : "" ) + dFmt.format(getRecordVelocity()) + )); + player.sendMessage( message1 ); + player.sendMessage( message2 ); + } // Reset key values: setJumping( false ); @@ -229,5 +248,16 @@ public double getRecordVelocity() { public void setRecordVelocity( double recordVelocity ) { this.recordVelocity = recordVelocity; } + + public boolean isDisplayMessages() { + return displayMessages; + } + public void setDisplayMessage(boolean displayMessages) { + this.displayMessages = displayMessages; + } + + public int getWorldHeight() { + return worldHeight; + } } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/slime/SlimeBlockFunEventListener.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/slime/SlimeBlockFunEventListener.java index 8b4f44971..7045a84d4 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/slime/SlimeBlockFunEventListener.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/slime/SlimeBlockFunEventListener.java @@ -1,11 +1,13 @@ package tech.mcprison.prison.spigot.slime; import java.text.DecimalFormat; +import java.util.Set; import java.util.TreeMap; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.block.Block; +import org.bukkit.configuration.ConfigurationSection; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; @@ -19,21 +21,69 @@ import tech.mcprison.prison.Prison; import tech.mcprison.prison.spigot.SpigotPrison; import tech.mcprison.prison.spigot.compat.SpigotCompatibility; +import tech.mcprison.prison.spigot.spiget.BluesSemanticVersionData; public class SlimeBlockFunEventListener implements Listener { private boolean enabled = false; - + private final TreeMap playerSlimeJumpCache; + + private final TreeMap boosters; + private final int worldHeight; + public SlimeBlockFunEventListener() { super(); this.playerSlimeJumpCache = new TreeMap<>(); - this.enabled = SpigotPrison.getInstance().getConfig().getBoolean("slime-fun"); + this.boosters = new TreeMap<>(); + + boolean enabled1 = SpigotPrison.getInstance().getConfig().getBoolean("slime-fun"); + boolean enabled2 = SpigotPrison.getInstance().getConfig().getBoolean("slime-fun.enabled"); + + this.enabled = enabled1 || enabled2; + + + ConfigurationSection mults = SpigotPrison.getInstance().getConfig().getConfigurationSection( "slime-fun.boosters" ); + + if ( mults != null ) { + + Set keys = mults.getKeys( false ); + + for (String key : keys) { + double mult = mults.getDouble( key ); + + if ( mult != 0 ) { + getBoosters().put( key.toLowerCase(), mult ); + } + } + } + else { + // No config is setup, so use these defaults: + getBoosters().put( "diamond_pickkaxe", 3.0 ); + getBoosters().put( "gold_pickaxe", 2.85 ); + getBoosters().put( "iron_pickaxe", 2.85 ); + getBoosters().put( "stone_pickaxe", 2.85 ); + getBoosters().put( "wood_pickaxe", 2.85 ); + getBoosters().put( "diamond_block", 1.65 ); + getBoosters().put( "gold_block", 1.45 ); + getBoosters().put( "iron_block", 1.20 ); + } + + + BluesSemanticVersionData bsvd = new BluesSemanticVersionData( Prison.get().getMinecraftVersion() ); + BluesSemanticVersionData bsvd18 = new BluesSemanticVersionData("1.18"); + + if ( bsvd.compareTo(bsvd18) >= 0 ) { + this.worldHeight = 320; + } + else { + this.worldHeight = 256; + } } @@ -91,11 +141,16 @@ else if ( velY > 0.2 ) { // Record player's System time stamp on Jump Boost: // Add player jump data to the cache: if ( !getPlayerSlimeJumpCache().containsKey( playerUUIDLSB ) ) { - SlimeBlockFunEventData moveEventData = new SlimeBlockFunEventData( playerUUIDLSB, loc.getY() ); + SlimeBlockFunEventData moveEventData = + new SlimeBlockFunEventData( playerUUIDLSB, loc.getY(), getWorldHeight() ); getPlayerSlimeJumpCache().put( playerUUIDLSB, moveEventData ); - player.sendMessage( "SlimeFun: Use at your own risk. Jumpping out of the " + - "world may crash the server." ); +// if ( moveEventData.isDisplayMessage() ) { +// +// player.sendMessage( "SlimeFun: Use at your own risk. Jumpping out of the " + +// "world may crash the server." ); +// } + } getPlayerSlimeJumpCache().get( playerUUIDLSB ) @@ -132,10 +187,18 @@ private Vector calculateVelocityY( double boost, Vector velocityOriginal, Player if ( velocityY > 1024.0 ) { - DecimalFormat f4Fmt = Prison.get().getDecimalFormat("#,##0.0000"); - player.sendMessage( "SlimeFun: Exceeded max velocity!! velY:" + + // Record player's System time stamp on Jump Boost: + Long playerUUIDLSB = Long.valueOf( player.getUniqueId().getLeastSignificantBits() ); + + if ( getPlayerSlimeJumpCache().containsKey( playerUUIDLSB ) && + getPlayerSlimeJumpCache().get( playerUUIDLSB ).isDisplayMessages() ) { + + DecimalFormat f4Fmt = Prison.get().getDecimalFormat("#,##0.0000"); + + player.sendMessage( "SlimeFun: Exceeded max velocity!! velY:" + f4Fmt.format( velocityY ) ); + } velocityY = 1024.0; } @@ -157,25 +220,31 @@ private double getBoost( ItemStack itemInHand ) // being ran. Material holding = itemInHand.getType(); - if ( holding == Material.DIAMOND_PICKAXE ) { - boost *= 3.0; - } - else if ( holding == Material.matchMaterial( "GOLD_PICKAXE" ) || - holding == Material.IRON_PICKAXE || - holding == Material.STONE_PICKAXE || - holding == Material.matchMaterial( "WOOD_PICKAXE" ) ) { - boost *= 2.85; - } - else if ( holding == Material.DIAMOND_BLOCK ) { - boost *= 1.65; - } - else if ( holding == Material.GOLD_BLOCK ) { - boost *= 1.45; - } - else if ( holding == Material.IRON_BLOCK ) { - boost *= 1.20; + String itemName = holding.name().toLowerCase(); + + if ( getBoosters().containsKey(itemName) ) { + boost *= getBoosters().get( itemName ); } +// if ( holding == Material.DIAMOND_PICKAXE ) { +// boost *= 3.0; +// } +// else if ( holding == Material.matchMaterial( "GOLD_PICKAXE" ) || +// holding == Material.IRON_PICKAXE || +// holding == Material.STONE_PICKAXE || +// holding == Material.matchMaterial( "WOOD_PICKAXE" ) ) { +// boost *= 2.85; +// } +// else if ( holding == Material.DIAMOND_BLOCK ) { +// boost *= 1.65; +// } +// else if ( holding == Material.GOLD_BLOCK ) { +// boost *= 1.45; +// } +// else if ( holding == Material.IRON_BLOCK ) { +// boost *= 1.20; +// } + // switch ( itemInHand.getType() ) // { @@ -246,5 +315,13 @@ public TreeMap getPlayerSlimeJumpCache() { return playerSlimeJumpCache; } + + public TreeMap getBoosters() { + return boosters; + } + + public int getWorldHeight() { + return worldHeight; + } } diff --git a/prison-spigot/src/main/resources/config.yml b/prison-spigot/src/main/resources/config.yml index 6d1958918..997b70c53 100644 --- a/prison-spigot/src/main/resources/config.yml +++ b/prison-spigot/src/main/resources/config.yml @@ -120,12 +120,27 @@ integrations: -# NEW: This enables new physics to be applied when jumpping on slime blocks. +# This enables new physics to be applied when jumpping on slime blocks. # When holding different items, like some block types or picks, the player can # jump even higher to heights of 40 to 60+ blocks. -slime-fun: false +# Boosters are items held in the primary hand of the player, which boosts the +# jump with each bounce. +slime-fun: + enabled: false + display-messages: true + boosters: + diamond_pickkaxe: 3.0 + gold_pickaxe: 2.85 + iron_pickaxe: 2.85 + stone_pickaxe: 2.85 + wood_pickaxe: 2.85 + diamond_block: 1.65 + gold_block: 1.45 + iron_block: 1.20 + + -# NEW: Prison now has GUIs for most features and actions. For more options +# Prison now has GUIs for most features and actions. For more options # please check the GuiConfig.yml. # Access with /gui prison-gui-enabled: true From d6e834ec84e5b6a20034e8c05065e3f770b64fbe Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Thu, 24 Aug 2023 20:08:19 -0400 Subject: [PATCH 083/151] AutoManager: percent gradient fortune: Changed the calculations to use doubles instead of integers. --- docs/changelog_v3.3.x.md | 3 +++ .../prison/spigot/autofeatures/AutoManagerFeatures.java | 6 +++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 4d05e7920..702bd2d1a 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -17,6 +17,9 @@ These change logs represent the work that has been going on within prison. # 3.3.0-alpha.15d 2023-08-24 +* **AutoManager: percent gradient fortune: Changed the calculations to use doubles instead of integers.** + + * **Slime-fun: Moved a lot of the settings for it to the config.yml file instead of hard coding them.** Now the messages can be turned off, and the boosters can now be added to, and changed. diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerFeatures.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerFeatures.java index 9b7bcde9d..92dcc1b2a 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerFeatures.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerFeatures.java @@ -2722,11 +2722,11 @@ else if ( isBoolean( AutoFeatures.isPercentGradientFortuneEnabled ) ) { int bonusBlocks = 0; double rnd = 1.0; - int maxFortune = getInteger( AutoFeatures.percentGradientFortuneMaxFortuneLevel ); + double maxFortune = getInteger( AutoFeatures.percentGradientFortuneMaxFortuneLevel ); int maxBonusBlocks = getInteger( AutoFeatures.percentGradientFortuneMaxBonusBlocks ); double minPctRnd = getDouble( AutoFeatures.percentGradientFortuneMinPercentRandomness ); - int fortLevel = fortuneLevelOriginal > maxFortune ? maxFortune : fortuneLevelOriginal; + double fortLevel = fortuneLevelOriginal > maxFortune ? maxFortune : fortuneLevelOriginal; if ( maxFortune > 0 && maxBonusBlocks > 1 ) { @@ -2737,7 +2737,7 @@ else if ( isBoolean( AutoFeatures.isPercentGradientFortuneEnabled ) ) { rnd = ((1.0 - (minPctRnd / 100)) * getRandom().nextDouble()) + (minPctRnd / 100); - bonusBlocks = ( fortLevel / maxFortune ) * maxBonusBlocks; + bonusBlocks = (int) Math.round( ( fortLevel / maxFortune ) * maxBonusBlocks ); bonusBlocks *= rnd; } From 29f39ae986bdee5f661797b407d1e8810fd6b35e Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Mon, 28 Aug 2023 18:22:32 -0400 Subject: [PATCH 084/151] Prison GUI: When disabled through the config.yml 'prison-gui-enabled: false' there were still some commands that were being registered with the '/gui' root. As a result, prison was taking over the use of the command '/gui' that was trying to be used by other plugins. This fix tries to isolate the GUI commands from backpacks, prestiges, and sellall, to make sure they cannot be registered if GUI is disabled. Had to create new classes to allow the isolation when registering the commands. --- docs/changelog_v3.3.x.md | 9 +- .../mcprison/prison/spigot/SpigotPrison.java | 62 ++++++-- .../PrisonSpigotBackpackCommands.java | 146 +++++++++--------- .../PrisonSpigotGUIBackPackCommands.java | 103 ++++++++++++ .../PrisonSpigotGUISellAllCommands.java | 77 +++++++++ .../commands/PrisonSpigotSellAllCommands.java | 116 +++++++------- 6 files changed, 371 insertions(+), 142 deletions(-) create mode 100644 prison-spigot/src/main/java/tech/mcprison/prison/spigot/commands/PrisonSpigotGUIBackPackCommands.java create mode 100644 prison-spigot/src/main/java/tech/mcprison/prison/spigot/commands/PrisonSpigotGUISellAllCommands.java diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 702bd2d1a..3716d99ed 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -14,7 +14,14 @@ These change logs represent the work that has been going on within prison. -# 3.3.0-alpha.15d 2023-08-24 +# 3.3.0-alpha.15d 2023-08-26 + + + +* **Prison GUI: When disabled through the config.yml 'prison-gui-enabled: false' there were still some commands that were being registered with the '/gui' root.** +As a result, prison was taking over the use of the command '/gui' that was trying to be used by other plugins. +This fix tries to isolate the GUI commands from backpacks, prestiges, and sellall, to make sure they cannot be registered if GUI is disabled. +Had to create new classes to allow the isolation when registering the commands. * **AutoManager: percent gradient fortune: Changed the calculations to use doubles instead of integers.** diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/SpigotPrison.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/SpigotPrison.java index b2a96010d..ebc08888c 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/SpigotPrison.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/SpigotPrison.java @@ -66,7 +66,9 @@ import tech.mcprison.prison.spigot.block.OnBlockBreakEventListener; import tech.mcprison.prison.spigot.bstats.PrisonBStats; import tech.mcprison.prison.spigot.commands.PrisonSpigotBackpackCommands; +import tech.mcprison.prison.spigot.commands.PrisonSpigotGUIBackPackCommands; import tech.mcprison.prison.spigot.commands.PrisonSpigotGUICommands; +import tech.mcprison.prison.spigot.commands.PrisonSpigotGUISellAllCommands; import tech.mcprison.prison.spigot.commands.PrisonSpigotMinesCommands; import tech.mcprison.prison.spigot.commands.PrisonSpigotPrestigeCommands; import tech.mcprison.prison.spigot.commands.PrisonSpigotRanksCommands; @@ -1035,14 +1037,18 @@ private void initModulesAndCommands() { YamlConfiguration modulesConf = loadConfig("modules.yml"); + boolean isMinesEnabled = false; boolean isRanksEnabled = false; // TODO: This business logic needs to be moved to the Module Manager: if (modulesConf.getBoolean("mines")) { + isMinesEnabled = true; + Prison.get().getModuleManager() .registerModule(new PrisonMines(getDescription().getVersion())); - Prison.get().getCommandHandler().registerCommands( new PrisonSpigotMinesCommands() ); + // The GUI handler for mines... cannot be hooked up here: +// Prison.get().getCommandHandler().registerCommands( new PrisonSpigotMinesCommands() ); } else { Output.get().logInfo("&7Modules: &cPrison Mines are disabled and were not Loaded. "); @@ -1120,13 +1126,14 @@ private void initModulesAndCommands() { // Do not enable sellall if ranks is not loaded since it uses player ranks: if ( isRanksEnabled ) { - Prison.get().getCommandHandler().registerCommands( new PrisonSpigotRanksCommands() ); + // enable under GUI: +// Prison.get().getCommandHandler().registerCommands( new PrisonSpigotRanksCommands() ); - // NOTE: If ranks module is enabled, then try to register prestiges commands if enabled: - if ( isPrisonConfig( "prestiges") || isPrisonConfig( "prestige.enabled" ) ) { - // Enable the setup of the prestige related commands only if prestiges is enabled: - Prison.get().getCommandHandler().registerCommands( new PrisonSpigotPrestigeCommands() ); - } +// // NOTE: If ranks module is enabled, then try to register prestiges commands if enabled: +// if ( isPrisonConfig( "prestiges") || isPrisonConfig( "prestige.enabled" ) ) { +// // Enable the setup of the prestige related commands only if prestiges is enabled: +// Prison.get().getCommandHandler().registerCommands( new PrisonSpigotPrestigeCommands() ); +// } } @@ -1137,11 +1144,46 @@ private void initModulesAndCommands() { } - // This registers the admin's /gui commands - // GUI commands were updated to prevent use of ranks commands when ranks module is not loaded. - if (getConfig().getString("prison-gui-enabled").equalsIgnoreCase("true")) { + // The following will enable all of the GUI related commands. It's important that they + // cannot be enabled elsewhere, or at least the 'prison-gui-enabled' must control + // their registration: + if ( Prison.get().getPlatform().getConfigBooleanFalse( "prison-gui-enabled" ) ) { + + // Prison's primary GUI commands: Prison.get().getCommandHandler().registerCommands( new PrisonSpigotGUICommands() ); + + + if ( isMinesEnabled ) { + // The GUI handler for mines... cannot be hooked up here: + Prison.get().getCommandHandler().registerCommands( new PrisonSpigotMinesCommands() ); + } + + + if ( isRanksEnabled ) { + Prison.get().getCommandHandler().registerCommands( new PrisonSpigotRanksCommands() ); + + // NOTE: If ranks module is enabled, then try to register prestiges commands if enabled: + if ( isPrisonConfig( "prestiges") || isPrisonConfig( "prestige.enabled" ) ) { + // Enable the setup of the prestige related commands only if prestiges is enabled: + Prison.get().getCommandHandler().registerCommands( new PrisonSpigotPrestigeCommands() ); + } + } + + + if ( isBackPacksEnabled ) { + Prison.get().getCommandHandler().registerCommands( new PrisonSpigotGUIBackPackCommands() ); + } + + + if ( isSellAllEnabled ) { + Prison.get().getCommandHandler().registerCommands( new PrisonSpigotGUISellAllCommands() ); + } } + +// // This registers the admin's /gui commands +// // GUI commands were updated to prevent use of ranks commands when ranks module is not loaded. +// if (getConfig().getString("prison-gui-enabled").equalsIgnoreCase("true")) { +// } // Register prison utility commands: diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/commands/PrisonSpigotBackpackCommands.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/commands/PrisonSpigotBackpackCommands.java index 403baa225..5c8648c2c 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/commands/PrisonSpigotBackpackCommands.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/commands/PrisonSpigotBackpackCommands.java @@ -278,79 +278,79 @@ private void openBackpackAdminGUI(CommandSender sender){ BackpacksAdminGUI gui = new BackpacksAdminGUI(p); gui.open(); } - - @Command(identifier = "gui backpack", description = "Backpack as a GUI", onlyPlayers = true) - private void backpackGUIOpenCommand(CommandSender sender, - @Arg(name = "Backpack-ID", def = "null", - description = "If user have more than backpack, he'll be able to choose another backpack on ID") String id){ - - Player p = getSpigotPlayer(sender); - - if (p == null) { - Output.get().sendInfo(sender, SpigotPrison.format( messages.getString(MessagesConfig.StringID.spigot_message_console_error))); - return; - } - - if (isDisabledWorld(p)) return; - - if (getBoolean(BackpacksUtil.get().getBackpacksConfig().getString("Options.Multiple-BackPacks-For-Player-Enabled")) && (BackpacksUtil.get().reachedBackpacksLimit(p) && !BackpacksUtil.get().getBackpacksIDs(p).contains(id))){ - Output.get().sendInfo(sender, SpigotPrison.format(messages.getString(MessagesConfig.StringID.spigot_message_backpack_limit_reached) + " [" + BackpacksUtil.get().getNumberOwnedBackpacks(p) + "]")); - return; - } - - if (getBoolean(BackpacksUtil.get().getBackpacksConfig().getString("Options.BackPack_Use_Permission_Enabled")) && !p.hasPermission(BackpacksUtil.get().getBackpacksConfig().getString("Options.BackPack_Use_Permission"))){ - Output.get().sendWarn(sender, SpigotPrison.format(messages.getString(MessagesConfig.StringID.spigot_message_missing_permission) + " [" + BackpacksUtil.get().getBackpacksConfig().getString("Options.BackPack_Use_Permission") + "]")); - return; - } - - if (!BackpacksUtil.get().canOwnBackpack(p)){ - Output.get().sendInfo(sender, SpigotPrison.format(messages.getString(MessagesConfig.StringID.spigot_message_backpack_cant_own))); - return; - } - - // New method. - if (!id.equalsIgnoreCase("null") && getBoolean(BackpacksUtil.get().getBackpacksConfig().getString("Options.Multiple-BackPacks-For-Player-Enabled"))){ - BackpacksUtil.get().openBackpack(p, id); - } else { - BackpacksUtil.get().openBackpack(p, (String) null ); - } - } - - @Command(identifier = "gui backpackslist", description = "Backpack as a GUI", onlyPlayers = true) - private void backpackListGUICommand(CommandSender sender){ - Player p = getSpigotPlayer(sender); - - if (p == null) { - Output.get().sendInfo(sender, SpigotPrison.format( messages.getString(MessagesConfig.StringID.spigot_message_console_error))); - return; - } - - if (isDisabledWorld(p)) return; - - // New method. - if (getBoolean(BackpacksUtil.get().getBackpacksConfig().getString("Options.Multiple-BackPacks-For-Player-Enabled"))){ - if (getBoolean(BackpacksUtil.get().getBackpacksConfig().getString("Options.BackPack_Use_Permission_Enabled")) && !p.hasPermission(BackpacksUtil.get().getBackpacksConfig().getString("Options.BackPack_Use_Permission"))){ - Output.get().sendWarn(sender, SpigotPrison.format(messages.getString(MessagesConfig.StringID.spigot_message_missing_permission) + " [" + BackpacksUtil.get().getBackpacksConfig().getString("Options.BackPack_Use_Permission") + "]")); - return; - } - BackpacksListPlayerGUI gui = new BackpacksListPlayerGUI(p); - gui.open(); - } - } - - @Command(identifier = "gui backpackadmin", description = "Open backpack admin GUI", permissions = "prison.admin", onlyPlayers = true) - private void openBackpackAdminCommandGUI(CommandSender sender){ - - Player p = getSpigotPlayer(sender); - - if (p == null) { - Output.get().sendInfo(sender, SpigotPrison.format( messages.getString(MessagesConfig.StringID.spigot_message_console_error))); - return; - } - - BackpacksAdminGUI gui = new BackpacksAdminGUI(p); - gui.open(); - } +// +// @Command(identifier = "gui backpack", description = "Backpack as a GUI", onlyPlayers = true) +// private void backpackGUIOpenCommand(CommandSender sender, +// @Arg(name = "Backpack-ID", def = "null", +// description = "If user have more than backpack, he'll be able to choose another backpack on ID") String id){ +// +// Player p = getSpigotPlayer(sender); +// +// if (p == null) { +// Output.get().sendInfo(sender, SpigotPrison.format( messages.getString(MessagesConfig.StringID.spigot_message_console_error))); +// return; +// } +// +// if (isDisabledWorld(p)) return; +// +// if (getBoolean(BackpacksUtil.get().getBackpacksConfig().getString("Options.Multiple-BackPacks-For-Player-Enabled")) && (BackpacksUtil.get().reachedBackpacksLimit(p) && !BackpacksUtil.get().getBackpacksIDs(p).contains(id))){ +// Output.get().sendInfo(sender, SpigotPrison.format(messages.getString(MessagesConfig.StringID.spigot_message_backpack_limit_reached) + " [" + BackpacksUtil.get().getNumberOwnedBackpacks(p) + "]")); +// return; +// } +// +// if (getBoolean(BackpacksUtil.get().getBackpacksConfig().getString("Options.BackPack_Use_Permission_Enabled")) && !p.hasPermission(BackpacksUtil.get().getBackpacksConfig().getString("Options.BackPack_Use_Permission"))){ +// Output.get().sendWarn(sender, SpigotPrison.format(messages.getString(MessagesConfig.StringID.spigot_message_missing_permission) + " [" + BackpacksUtil.get().getBackpacksConfig().getString("Options.BackPack_Use_Permission") + "]")); +// return; +// } +// +// if (!BackpacksUtil.get().canOwnBackpack(p)){ +// Output.get().sendInfo(sender, SpigotPrison.format(messages.getString(MessagesConfig.StringID.spigot_message_backpack_cant_own))); +// return; +// } +// +// // New method. +// if (!id.equalsIgnoreCase("null") && getBoolean(BackpacksUtil.get().getBackpacksConfig().getString("Options.Multiple-BackPacks-For-Player-Enabled"))){ +// BackpacksUtil.get().openBackpack(p, id); +// } else { +// BackpacksUtil.get().openBackpack(p, (String) null ); +// } +// } +// +// @Command(identifier = "gui backpackslist", description = "Backpack as a GUI", onlyPlayers = true) +// private void backpackListGUICommand(CommandSender sender){ +// Player p = getSpigotPlayer(sender); +// +// if (p == null) { +// Output.get().sendInfo(sender, SpigotPrison.format( messages.getString(MessagesConfig.StringID.spigot_message_console_error))); +// return; +// } +// +// if (isDisabledWorld(p)) return; +// +// // New method. +// if (getBoolean(BackpacksUtil.get().getBackpacksConfig().getString("Options.Multiple-BackPacks-For-Player-Enabled"))){ +// if (getBoolean(BackpacksUtil.get().getBackpacksConfig().getString("Options.BackPack_Use_Permission_Enabled")) && !p.hasPermission(BackpacksUtil.get().getBackpacksConfig().getString("Options.BackPack_Use_Permission"))){ +// Output.get().sendWarn(sender, SpigotPrison.format(messages.getString(MessagesConfig.StringID.spigot_message_missing_permission) + " [" + BackpacksUtil.get().getBackpacksConfig().getString("Options.BackPack_Use_Permission") + "]")); +// return; +// } +// BackpacksListPlayerGUI gui = new BackpacksListPlayerGUI(p); +// gui.open(); +// } +// } +// +// @Command(identifier = "gui backpackadmin", description = "Open backpack admin GUI", permissions = "prison.admin", onlyPlayers = true) +// private void openBackpackAdminCommandGUI(CommandSender sender){ +// +// Player p = getSpigotPlayer(sender); +// +// if (p == null) { +// Output.get().sendInfo(sender, SpigotPrison.format( messages.getString(MessagesConfig.StringID.spigot_message_console_error))); +// return; +// } +// +// BackpacksAdminGUI gui = new BackpacksAdminGUI(p); +// gui.open(); +// } private boolean isDisabledWorld(Player p) { String worldName = p.getWorld().getName(); diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/commands/PrisonSpigotGUIBackPackCommands.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/commands/PrisonSpigotGUIBackPackCommands.java new file mode 100644 index 000000000..b301ba73e --- /dev/null +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/commands/PrisonSpigotGUIBackPackCommands.java @@ -0,0 +1,103 @@ +package tech.mcprison.prison.spigot.commands; + +import java.util.List; + +import org.bukkit.entity.Player; + +import tech.mcprison.prison.commands.Arg; +import tech.mcprison.prison.commands.Command; +import tech.mcprison.prison.internal.CommandSender; +import tech.mcprison.prison.output.Output; +import tech.mcprison.prison.spigot.SpigotPrison; +import tech.mcprison.prison.spigot.backpacks.BackpacksUtil; +import tech.mcprison.prison.spigot.configs.MessagesConfig; +import tech.mcprison.prison.spigot.gui.backpacks.BackpacksAdminGUI; +import tech.mcprison.prison.spigot.gui.backpacks.BackpacksListPlayerGUI; + +public class PrisonSpigotGUIBackPackCommands + extends PrisonSpigotBaseCommands +{ + + private final MessagesConfig messages = SpigotPrison.getInstance().getMessagesConfig(); + + @Command(identifier = "gui backpack", description = "Backpack as a GUI", onlyPlayers = true) + private void backpackGUIOpenCommand(CommandSender sender, + @Arg(name = "Backpack-ID", def = "null", + description = "If user have more than backpack, he'll be able to choose another backpack on ID") String id){ + + Player p = getSpigotPlayer(sender); + + if (p == null) { + Output.get().sendInfo(sender, SpigotPrison.format( messages.getString(MessagesConfig.StringID.spigot_message_console_error))); + return; + } + + if (isDisabledWorld(p)) return; + + if (getBoolean(BackpacksUtil.get().getBackpacksConfig().getString("Options.Multiple-BackPacks-For-Player-Enabled")) && (BackpacksUtil.get().reachedBackpacksLimit(p) && !BackpacksUtil.get().getBackpacksIDs(p).contains(id))){ + Output.get().sendInfo(sender, SpigotPrison.format(messages.getString(MessagesConfig.StringID.spigot_message_backpack_limit_reached) + " [" + BackpacksUtil.get().getNumberOwnedBackpacks(p) + "]")); + return; + } + + if (getBoolean(BackpacksUtil.get().getBackpacksConfig().getString("Options.BackPack_Use_Permission_Enabled")) && !p.hasPermission(BackpacksUtil.get().getBackpacksConfig().getString("Options.BackPack_Use_Permission"))){ + Output.get().sendWarn(sender, SpigotPrison.format(messages.getString(MessagesConfig.StringID.spigot_message_missing_permission) + " [" + BackpacksUtil.get().getBackpacksConfig().getString("Options.BackPack_Use_Permission") + "]")); + return; + } + + if (!BackpacksUtil.get().canOwnBackpack(p)){ + Output.get().sendInfo(sender, SpigotPrison.format(messages.getString(MessagesConfig.StringID.spigot_message_backpack_cant_own))); + return; + } + + // New method. + if (!id.equalsIgnoreCase("null") && getBoolean(BackpacksUtil.get().getBackpacksConfig().getString("Options.Multiple-BackPacks-For-Player-Enabled"))){ + BackpacksUtil.get().openBackpack(p, id); + } else { + BackpacksUtil.get().openBackpack(p, (String) null ); + } + } + + @Command(identifier = "gui backpackslist", description = "Backpack as a GUI", onlyPlayers = true) + private void backpackListGUICommand(CommandSender sender){ + Player p = getSpigotPlayer(sender); + + if (p == null) { + Output.get().sendInfo(sender, SpigotPrison.format( messages.getString(MessagesConfig.StringID.spigot_message_console_error))); + return; + } + + if (isDisabledWorld(p)) return; + + // New method. + if (getBoolean(BackpacksUtil.get().getBackpacksConfig().getString("Options.Multiple-BackPacks-For-Player-Enabled"))){ + if (getBoolean(BackpacksUtil.get().getBackpacksConfig().getString("Options.BackPack_Use_Permission_Enabled")) && !p.hasPermission(BackpacksUtil.get().getBackpacksConfig().getString("Options.BackPack_Use_Permission"))){ + Output.get().sendWarn(sender, SpigotPrison.format(messages.getString(MessagesConfig.StringID.spigot_message_missing_permission) + " [" + BackpacksUtil.get().getBackpacksConfig().getString("Options.BackPack_Use_Permission") + "]")); + return; + } + BackpacksListPlayerGUI gui = new BackpacksListPlayerGUI(p); + gui.open(); + } + } + + @Command(identifier = "gui backpackadmin", description = "Open backpack admin GUI", permissions = "prison.admin", onlyPlayers = true) + private void openBackpackAdminCommandGUI(CommandSender sender){ + + Player p = getSpigotPlayer(sender); + + if (p == null) { + Output.get().sendInfo(sender, SpigotPrison.format( messages.getString(MessagesConfig.StringID.spigot_message_console_error))); + return; + } + + BackpacksAdminGUI gui = new BackpacksAdminGUI(p); + gui.open(); + } + + + private boolean isDisabledWorld(Player p) { + String worldName = p.getWorld().getName(); + List disabledWorlds = BackpacksUtil.get().getBackpacksConfig().getStringList("Options.DisabledWorlds"); + return disabledWorlds.contains(worldName); + } + +} diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/commands/PrisonSpigotGUISellAllCommands.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/commands/PrisonSpigotGUISellAllCommands.java new file mode 100644 index 000000000..8f5274c32 --- /dev/null +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/commands/PrisonSpigotGUISellAllCommands.java @@ -0,0 +1,77 @@ +package tech.mcprison.prison.spigot.commands; + +import org.bukkit.entity.Player; + +import tech.mcprison.prison.commands.Arg; +import tech.mcprison.prison.commands.Command; +import tech.mcprison.prison.internal.CommandSender; +import tech.mcprison.prison.output.Output; +import tech.mcprison.prison.sellall.messages.SpigotVariousGuiMessages; +import tech.mcprison.prison.spigot.configs.MessagesConfig; +import tech.mcprison.prison.spigot.gui.sellall.SellAllAdminBlocksGUI; +import tech.mcprison.prison.spigot.sellall.SellAllUtil; + +public class PrisonSpigotGUISellAllCommands + extends PrisonSpigotBaseCommands { + + + @Command(identifier = "sellall gui", + description = "SellAll GUI command", +// aliases = "gui sellall", + permissions = "prison.admin", onlyPlayers = true) + private void sellAllGuiCommand(CommandSender sender, + @Arg(name = "page", description = "If there are more than 45 items, then they " + + "will be shown on multiple pages. The page parameter starts with " + + "page 1.", def = "1" ) int page){ + + if (!PrisonSpigotSellAllCommands.isEnabled()) return; + + Player p = getSpigotPlayer(sender); + + // Sender must be a Player, not something else like the Console. + if (p == null) { + Output.get().sendError(sender, getMessages().getString(MessagesConfig.StringID.spigot_message_console_error)); + return; + } + + SellAllUtil sellAllUtil = SellAllUtil.get(); + if (sellAllUtil == null){ + return; + } + + if (!sellAllUtil.openSellAllGUI( p, page, "sellall gui", "close" )){ + // If the sender's an admin (OP or have the prison.admin permission) it'll send an error message. + if (p.hasPermission("prison.admin")) { + + new SpigotVariousGuiMessages().sellallGUIIsDisabledMsg(sender); +// Output.get().sendError(sender, +// messages.getString(MessagesConfig.StringID.spigot_message_gui_sellall_disabled)); + } + } + } + + @Command(identifier = "sellall gui blocks", + description = "SellAll GUI Blocks command", + aliases = "gui sellall", + permissions = "prison.admin", onlyPlayers = true) + private void sellAllGuiBlocksCommand(CommandSender sender, + @Arg(name = "page", description = "If there are more than 45 items, then they " + + "will be shown on multiple pages. The page parameter starts with " + + "page 1.", def = "1" ) int page){ + + if (!PrisonSpigotSellAllCommands.isEnabled()) return; + + Player p = getSpigotPlayer(sender); + + // Sender must be a Player, not something else like the Console. + if (p == null) { + Output.get().sendError(sender, getMessages().getString(MessagesConfig.StringID.spigot_message_console_error)); + return; + } + + SellAllAdminBlocksGUI saBlockGui = new SellAllAdminBlocksGUI( p, page, "sellall gui blocks", "sellall gui" ); + saBlockGui.open(); + + } + +} diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/commands/PrisonSpigotSellAllCommands.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/commands/PrisonSpigotSellAllCommands.java index b69306ae9..89b8a8342 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/commands/PrisonSpigotSellAllCommands.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/commands/PrisonSpigotSellAllCommands.java @@ -625,65 +625,65 @@ private void sellAllAutoEnableUser(CommandSender sender){ } } } - - @Command(identifier = "sellall gui", - description = "SellAll GUI command", +// +// @Command(identifier = "sellall gui", +// description = "SellAll GUI command", +//// aliases = "gui sellall", +// permissions = "prison.admin", onlyPlayers = true) +// private void sellAllGuiCommand(CommandSender sender, +// @Arg(name = "page", description = "If there are more than 45 items, then they " + +// "will be shown on multiple pages. The page parameter starts with " + +// "page 1.", def = "1" ) int page){ +// +// if (!isEnabled()) return; +// +// Player p = getSpigotPlayer(sender); +// +// // Sender must be a Player, not something else like the Console. +// if (p == null) { +// Output.get().sendError(sender, getMessages().getString(MessagesConfig.StringID.spigot_message_console_error)); +// return; +// } +// +// SellAllUtil sellAllUtil = SellAllUtil.get(); +// if (sellAllUtil == null){ +// return; +// } +// +// if (!sellAllUtil.openSellAllGUI( p, page, "sellall gui", "close" )){ +// // If the sender's an admin (OP or have the prison.admin permission) it'll send an error message. +// if (p.hasPermission("prison.admin")) { +// +// new SpigotVariousGuiMessages().sellallGUIIsDisabledMsg(sender); +//// Output.get().sendError(sender, +//// messages.getString(MessagesConfig.StringID.spigot_message_gui_sellall_disabled)); +// } +// } +// } +// +// @Command(identifier = "sellall gui blocks", +// description = "SellAll GUI Blocks command", // aliases = "gui sellall", - permissions = "prison.admin", onlyPlayers = true) - private void sellAllGuiCommand(CommandSender sender, - @Arg(name = "page", description = "If there are more than 45 items, then they " + - "will be shown on multiple pages. The page parameter starts with " + - "page 1.", def = "1" ) int page){ - - if (!isEnabled()) return; - - Player p = getSpigotPlayer(sender); - - // Sender must be a Player, not something else like the Console. - if (p == null) { - Output.get().sendError(sender, getMessages().getString(MessagesConfig.StringID.spigot_message_console_error)); - return; - } - - SellAllUtil sellAllUtil = SellAllUtil.get(); - if (sellAllUtil == null){ - return; - } - - if (!sellAllUtil.openSellAllGUI( p, page, "sellall gui", "close" )){ - // If the sender's an admin (OP or have the prison.admin permission) it'll send an error message. - if (p.hasPermission("prison.admin")) { - - new SpigotVariousGuiMessages().sellallGUIIsDisabledMsg(sender); -// Output.get().sendError(sender, -// messages.getString(MessagesConfig.StringID.spigot_message_gui_sellall_disabled)); - } - } - } - - @Command(identifier = "sellall gui blocks", - description = "SellAll GUI Blocks command", - aliases = "gui sellall", - permissions = "prison.admin", onlyPlayers = true) - private void sellAllGuiBlocksCommand(CommandSender sender, - @Arg(name = "page", description = "If there are more than 45 items, then they " + - "will be shown on multiple pages. The page parameter starts with " + - "page 1.", def = "1" ) int page){ - - if (!isEnabled()) return; - - Player p = getSpigotPlayer(sender); - - // Sender must be a Player, not something else like the Console. - if (p == null) { - Output.get().sendError(sender, getMessages().getString(MessagesConfig.StringID.spigot_message_console_error)); - return; - } - - SellAllAdminBlocksGUI saBlockGui = new SellAllAdminBlocksGUI( p, page, "sellall gui blocks", "sellall gui" ); - saBlockGui.open(); - - } +// permissions = "prison.admin", onlyPlayers = true) +// private void sellAllGuiBlocksCommand(CommandSender sender, +// @Arg(name = "page", description = "If there are more than 45 items, then they " + +// "will be shown on multiple pages. The page parameter starts with " + +// "page 1.", def = "1" ) int page){ +// +// if (!isEnabled()) return; +// +// Player p = getSpigotPlayer(sender); +// +// // Sender must be a Player, not something else like the Console. +// if (p == null) { +// Output.get().sendError(sender, getMessages().getString(MessagesConfig.StringID.spigot_message_console_error)); +// return; +// } +// +// SellAllAdminBlocksGUI saBlockGui = new SellAllAdminBlocksGUI( p, page, "sellall gui blocks", "sellall gui" ); +// saBlockGui.open(); +// +// } @Command(identifier = "sellall items add", description = "This will add an item to the SellAll shop. " From 4ddfc50a1361876cf63bf7a4deb5a184dc65c628 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 2 Sep 2023 23:14:12 -0400 Subject: [PATCH 085/151] AutoFeatures and prison version: I have no idea why I added an auto features reload when doing prison version. Removed. Best guess at this moment is that it was to test something. --- docs/changelog_v3.3.x.md | 6 +++++- .../java/tech/mcprison/prison/spigot/SpigotPlatform.java | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 3716d99ed..93d66b4dc 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -14,10 +14,14 @@ These change logs represent the work that has been going on within prison. -# 3.3.0-alpha.15d 2023-08-26 +# 3.3.0-alpha.15d 2023-09-01 +* **AutoFeatures and prison version: I have no idea why I added an auto features reload when doing prison version. Removed.** +Best guess at this moment is that it was to test something. + + * **Prison GUI: When disabled through the config.yml 'prison-gui-enabled: false' there were still some commands that were being registered with the '/gui' root.** As a result, prison was taking over the use of the command '/gui' that was trying to be used by other plugins. This fix tries to isolate the GUI commands from backpacks, prestiges, and sellall, to make sure they cannot be registered if GUI is disabled. diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/SpigotPlatform.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/SpigotPlatform.java index 591c7a5a1..e2fac05db 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/SpigotPlatform.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/SpigotPlatform.java @@ -2170,7 +2170,7 @@ public List getActiveFeatures( boolean showLaddersAndRanks ) { // Load the autoFeaturesConfig.yml and blockConvertersConfig.json files: AutoFeaturesWrapper afw = AutoFeaturesWrapper.getInstance(); - afw.reloadConfigs(); +// afw.reloadConfigs(); boolean isAutoManagerEnabled = afw.isBoolean( AutoFeatures.isAutoManagerEnabled ); From cae0aea9e76c23e3a65f7de06334e078ea7e7153 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 2 Sep 2023 23:28:44 -0400 Subject: [PATCH 086/151] Mine wand debug info: Slightly alter the printing of the details to make it easier to read. --- docs/changelog_v3.3.x.md | 5 +- .../events/PrisonDebugBlockInspector.java | 62 ++++++++++++------- 2 files changed, 45 insertions(+), 22 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 93d66b4dc..1b71dba6e 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -14,7 +14,10 @@ These change logs represent the work that has been going on within prison. -# 3.3.0-alpha.15d 2023-09-01 +# 3.3.0-alpha.15d 2023-09-02 + + +* **Mine wand debug info: Slightly alter the printing of the details to make it easier to read.** diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/PrisonDebugBlockInspector.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/PrisonDebugBlockInspector.java index 77a531c71..0ddd9ffd0 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/PrisonDebugBlockInspector.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/PrisonDebugBlockInspector.java @@ -102,6 +102,9 @@ private void init() { @Subscribe public void onPlayerInteract( PrisonPlayerInteractEvent e ) { + List output = new ArrayList<>(); + + // Cool down: run no sooner than every 2 seconds... prevents duplicate runs: if ( lastAccess != 0 && (System.currentTimeMillis() - lastAccess) < 2000 ) { return; @@ -134,9 +137,9 @@ public void onPlayerInteract( PrisonPlayerInteractEvent e ) { if ( mine == null ) { - player.sendMessage( + output.add( String.format( - "&dDebugBlockInfo: &7Not in a mine. &5%s &7%s", + "-&dDebugBlockInfo: &7Not in a mine. &5%s &7%s", sBlock.getBlockName(), location.toWorldCoordinates()) ); } @@ -152,21 +155,24 @@ public void onPlayerInteract( PrisonPlayerInteractEvent e ) { // checkForCustomBlock( sBlock, targetBlock ); String m1 = String.format( - "&dDebugBlockInfo: &3Mine &7%s &3Rank: &7%s " + - "&5%s &7%s", + "-&dDebugBlockInfo: &3Mine &7%s &3Rank: &7%s " + + "&5%s &7%s ", mine.getName(), (mine.getRank() == null ? "---" : mine.getRank().getName()), sBlock.getBlockName(), location.toWorldCoordinates()); - player.sendMessage( m1 ); - Output.get().logInfo( m1 ); + output.add( m1 ); +// player.sendMessage( m1 ); +// Output.get().logInfo( m1 ); // Get the mine's targetBlock: // MineTargetPrisonBlock tBlock = mine.getTargetPrisonBlock( sBlock ); if ( targetBlock == null ) { - player.sendMessage( "Notice: Unable to get a mine's targetBlock. This could imply " + + + + output.add( "-Notice: Unable to get a mine's targetBlock. This could imply " + "that the mine was not reset since the server started up, or that the air-block " + "check was not ran yet. Use `/mine reset " + mine.getName() + "' to reset the " + "target blocks." ); @@ -174,7 +180,7 @@ public void onPlayerInteract( PrisonPlayerInteractEvent e ) { else { - String message = String.format( " &3TargetBlock: &7%s " + + String message = String.format( "- &3TargetBlock: &7%s " + "&3Mined: %s%b &3Broke: &7%b &3Counted: &7%b", targetBlock.getPrisonBlock().getBlockName(), (targetBlock.isMined() ? "&d" : "&2"), @@ -183,10 +189,11 @@ public void onPlayerInteract( PrisonPlayerInteractEvent e ) { targetBlock.isCounted() ); - player.sendMessage( message ); - Output.get().logInfo( message ); + output.add( message ); +// player.sendMessage( message ); +// Output.get().logInfo( message ); - String message2 = String.format( " &3isEdge: &7%b " + + String message2 = String.format( "- &3isEdge: &7%b " + "&3Exploded: %s%b &3IgnoreAllEvents: &7%b", targetBlock.isEdge(), @@ -195,15 +202,16 @@ public void onPlayerInteract( PrisonPlayerInteractEvent e ) { targetBlock.isIgnoreAllBlockEvents() ); - player.sendMessage( message2 ); - Output.get().logInfo( message2 ); + output.add( message2 ); +// player.sendMessage( message2 ); +// Output.get().logInfo( message2 ); } } if ( !isSneaking ) { - player.sendMessage( + output.add( String.format( " &d(&7Sneak to test BlockBreakEvent with block.&d)" ) ); @@ -217,11 +225,22 @@ public void onPlayerInteract( PrisonPlayerInteractEvent e ) { // Debug the block break events: - dumpBlockBreakEvent( player, sBlock, targetBlock ); + dumpBlockBreakEvent( player, sBlock, targetBlock, output ); } + + output.add( " - - End DebugBlockInfo - - " ); + for ( String outputLine : output ) { + boolean playerMessage = outputLine.startsWith( "-" ); + if ( playerMessage ) { + outputLine = outputLine.substring( 1 ); + + player.sendMessage( outputLine ); + } + Output.get().logInfo( outputLine ); + } @@ -250,8 +269,9 @@ public void onPlayerInteract( PrisonPlayerInteractEvent e ) { } - public void dumpBlockBreakEvent( SpigotPlayer player, SpigotBlock sBlock, MineTargetPrisonBlock targetBlock ) { - List output = new ArrayList<>(); + public void dumpBlockBreakEvent( SpigotPlayer player, SpigotBlock sBlock, MineTargetPrisonBlock targetBlock, + List output ) { +// List output = new ArrayList<>(); SpigotBlock checkBlock = sBlock; @@ -380,10 +400,10 @@ public void dumpBlockBreakEvent( SpigotPlayer player, SpigotBlock sBlock, MineTa // Put the heldItem back in the player's hand, which should be the prison wand: SpigotCompatibility.getInstance().setItemInMainHand( player.getWrapper(), heldItem ); - for ( String outputLine : output ) - { - Output.get().logInfo( outputLine ); - } +// for ( String outputLine : output ) +// { +// Output.get().logInfo( outputLine ); +// } } From 0ed187ef78cb1fc5c6ef68a1edfa34ef5eff9fd3 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sun, 3 Sep 2023 04:13:08 -0400 Subject: [PATCH 087/151] Prison messages: Expanded the use of prison message line breaks, `{br}` in both console messages and sending messages to player. Auto Features: Added line breaks to the existing block break debug info since it's very long and difficult to read. --- docs/changelog_v3.3.x.md | 6 ++- .../tech/mcprison/prison/output/Output.java | 21 +++++++--- .../autofeatures/AutoManagerFeatures.java | 40 +++++++++++-------- .../spigot/block/OnBlockBreakEventCore.java | 6 ++- .../spigot/block/OnBlockBreakMines.java | 2 +- 5 files changed, 51 insertions(+), 24 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 1b71dba6e..147d38ada 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -14,7 +14,11 @@ These change logs represent the work that has been going on within prison. -# 3.3.0-alpha.15d 2023-09-02 +# 3.3.0-alpha.15d 2023-09-03 + + +* **Prison messages: Expanded the use of prison message line breaks, `{br}` in both console messages and sending messages to player.** +Auto Features: Added line breaks to the existing block break debug info since it's very long and difficult to read. * **Mine wand debug info: Slightly alter the printing of the details to make it easier to read.** diff --git a/prison-core/src/main/java/tech/mcprison/prison/output/Output.java b/prison-core/src/main/java/tech/mcprison/prison/output/Output.java index 03d11b301..c14f77a3c 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/output/Output.java +++ b/prison-core/src/main/java/tech/mcprison/prison/output/Output.java @@ -40,6 +40,8 @@ public class Output public static final String PERCENT_ENCODING = "%"; public static final String PERCENT_DECODING = "%"; + public static final String LINE_SPLITING = "\\{br\\}"; +// public static final String LINE_SPLITING = "\n"; private static Output instance; @@ -279,10 +281,15 @@ else if ( Prison.get() == null || Prison.get().getPlatform() == null ) { // msg = msg.replace( PERCENT_ENCODING, PERCENT_DECODING ); // } - Prison.get().getPlatform().log( - prefixTemplatePrison + " " + - getLogColorCode(level) + - msg); + String msgRaw = String.format(msg, args); + for (String msgSplit : msgRaw.split( LINE_SPLITING )) { + + Prison.get().getPlatform().log( + prefixTemplatePrison + " " + + getLogColorCode(level) + + msgSplit); + } + } catch ( MissingFormatArgumentException e ) { @@ -578,7 +585,11 @@ public void sendMessage(CommandSender sender, String message, LogLevel level, Ob if ( level == null ) { level = LogLevel.PLAIN; } - sender.sendMessage(getLogPrefix(level) + String.format(message, args)); + String msgRaw = String.format(message, args); + for (String msg : msgRaw.split( LINE_SPLITING )) { + + sender.sendMessage(getLogPrefix(level) + msg); + } } } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerFeatures.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerFeatures.java index 92dcc1b2a..1b5ae337f 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerFeatures.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerFeatures.java @@ -153,7 +153,9 @@ protected void printDebugInfo( PrisonMinesBlockBreakEvent pmEvent, double start if ( pmEvent != null && pmEvent.getDebugInfo().length() > 0 ) { long stop = System.nanoTime(); - pmEvent.getDebugInfo().append( " [" ).append( (stop - start) / 1000000d ).append( " ms]" ); + pmEvent.getDebugInfo().append( "{br}### ** End Event Debug Info ** ### [" ) + .append( (stop - start) / 1000000d ) + .append( " ms]" ); if ( !Output.get().isDebug() && pmEvent.isForceDebugLogging() ) { @@ -539,11 +541,16 @@ private int applyAutoEventsDetails( PrisonMinesBlockBreakEvent pmEvent ) { if ( Output.get().isDebug( DebugTarget.blockBreak ) ) { - pmEvent.getDebugInfo().append( "(applyAutoEvents: " ) + pmEvent.getDebugInfo().append( "{br} (applyAutoEvents: " ) .append( pmEvent.getSpigotBlock().getBlockName() ); if ( !isAutoFeaturesEnabled ) { - pmEvent.getDebugInfo().append("isAutoFeaturesEnabled=false (disabled)"); + pmEvent.getDebugInfo().append(" isAutoFeaturesEnabled=false ("); + + pmEvent.getDebugInfo().append( Output.get().getColorCodeError() ); + pmEvent.getDebugInfo().append("disabled"); + pmEvent.getDebugInfo().append( Output.get().getColorCodeDebug() ); + pmEvent.getDebugInfo().append(")"); } else { @@ -598,7 +605,7 @@ private int applyAutoEventsDetails( PrisonMinesBlockBreakEvent pmEvent ) { if ( configNormalDrop ) { pmEvent.getDebugInfo() - .append( "(NormalDrop handling enabled: " ) + .append( "{br} (NormalDrop handling enabled: " ) .append( "normalDropSmelt[" ) .append( configNormalDropSmelt ? "enabled" : "disabled" ) .append( "] " ) @@ -799,7 +806,7 @@ protected int autoPickup( PrisonMinesBlockBreakEvent pmEvent, sb.insert( 0, "bukkitDropMult=" ); } - debugInfo.append( "[autoPickupDrops:beforeFortune:: " ).append( sb ).append( "] "); + debugInfo.append( "{br} [autoPickupDrops:beforeFortune:: " ).append( sb ).append( "] "); @@ -831,7 +838,7 @@ protected int autoPickup( PrisonMinesBlockBreakEvent pmEvent, .append( ":" ) .append( itemStack.getAmount() ); } - debugInfo.append( "[totalDrops:afterFortune:: " ).append( sb ).append( "] "); + debugInfo.append( "{br} [totalDrops:afterFortune:: " ).append( sb ).append( "] "); } @@ -842,14 +849,14 @@ protected int autoPickup( PrisonMinesBlockBreakEvent pmEvent, // Smelt if ( isAutoSmelt ) { - debugInfo.append( "(autoSmelting: itemStacks)" ); + debugInfo.append( "(autoSmelting: drops)" ); normalDropSmelt( drops ); } // Block if ( isAutoBlock ) { - debugInfo.append( "(autoBlocking: itemStacks)" ); + debugInfo.append( "(autoBlocking: drops)" ); normalDropBlock( drops ); } @@ -988,7 +995,7 @@ protected int autoPickup( PrisonMinesBlockBreakEvent pmEvent, double amount = SellAllUtil.get().getItemStackValue( pmEvent.getSpigotPlayer(), itemStack ); autosellTotal += amount; - debugInfo.append( "(WARNING: autosell leftovers: " + itemStack.getName() + + debugInfo.append( "{br} (WARNING: autosell leftovers: " + itemStack.getName() + " qty: " + itemStack.getAmount() + " value: " + dFmt.format( amount ) + " - " + ( amount == 0 ? " Items NOT in sellall shop!" : " CouldNotSell?") + @@ -1002,7 +1009,7 @@ protected int autoPickup( PrisonMinesBlockBreakEvent pmEvent, double amount = SellAllUtil.get().getItemStackValue( pmEvent.getSpigotPlayer(), itemStack ); autosellTotal += amount; - debugInfo.append( "(Debug-unsold-value-check: " + itemStack.getName() + + debugInfo.append( "{br} (Debug-unsold-value-check: " + itemStack.getName() + " qty: " + itemStack.getAmount() + " value: " + dFmt.format( amount ) + ") "); } @@ -1038,7 +1045,7 @@ protected int autoPickup( PrisonMinesBlockBreakEvent pmEvent, if ( count > 0 || autosellTotal > 0 ) { - debugInfo.append( "[autoPickupDrops total: qty: " + count + " value: " + dFmt.format( autosellTotal ) + + debugInfo.append( "{br} [autoPickupDrops total: qty: " + count + " value: " + dFmt.format( autosellTotal ) + " unsellableCount: " + autosellUnsellableCount ); if ( nanoTime > 0 ) { @@ -1121,7 +1128,7 @@ public int calculateNormalDrop( PrisonMinesBlockBreakEvent pmEvent ) { sb.insert( 0, "bukkitDropMult=" ); } - pmEvent.getDebugInfo().append( "[normalDrops:: " ).append( sb ).append( "] "); + pmEvent.getDebugInfo().append( "{br} [normalDrops:: " ).append( sb ).append( "] "); // Need better drop calculation that is not using the getDrops function. @@ -1149,13 +1156,13 @@ public int calculateNormalDrop( PrisonMinesBlockBreakEvent pmEvent ) { if ( isBoolean( AutoFeatures.normalDropSmelt ) ) { - pmEvent.getDebugInfo().append( "(normSmelting: itemStacks)" ); + pmEvent.getDebugInfo().append( "(normSmelting: drops)" ); normalDropSmelt( drops ); } if ( isBoolean( AutoFeatures.normalDropBlock ) ) { - pmEvent.getDebugInfo().append( "(normBlocking: itemStacks)" ); + pmEvent.getDebugInfo().append( "(normBlocking: drops)" ); normalDropBlock( drops ); } @@ -1172,6 +1179,7 @@ public int calculateNormalDrop( PrisonMinesBlockBreakEvent pmEvent ) { // } + pmEvent.getDebugInfo().append( "{br} " ); double autosellTotal = 0; @@ -1224,7 +1232,7 @@ public int calculateNormalDrop( PrisonMinesBlockBreakEvent pmEvent ) { if ( count > 0 || autosellTotal > 0 ) { - pmEvent.getDebugInfo().append( "[normalDrops total: qty: " + count + " value: " + autosellTotal + ") "); + pmEvent.getDebugInfo().append( "{br} [normalDrops total: qty: " + count + " value: " + autosellTotal + "] "); } @@ -2744,7 +2752,7 @@ else if ( isBoolean( AutoFeatures.isPercentGradientFortuneEnabled ) ) { // The count has the final value so set it as the amount: blocks.setAmount( 1 + bonusBlocks ); - + String msg = String.format( "(gradientFortune blocks: 1 + bonusBlocks=%s == (fortLevel=%s / maxFortLevel=%s) * " + "maxBonusBlocks=%s * rnd=%s [with minPctRnd=%s]) ", diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/block/OnBlockBreakEventCore.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/block/OnBlockBreakEventCore.java index 11d927ba4..726a1bfd0 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/block/OnBlockBreakEventCore.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/block/OnBlockBreakEventCore.java @@ -348,6 +348,8 @@ protected boolean validateEvent( PrisonMinesBlockBreakEvent pmEvent ) StringBuilder debugInfo = pmEvent.getDebugInfo(); + debugInfo.append( "{br} validateEvent:: " ); + SpigotBlock sBlockHit = pmEvent.getSpigotBlock(); // Mine should already be set: @@ -751,7 +753,7 @@ else if ( targetExplodedBlock.isMined() ) { } - debugInfo.append( "blocks(" ) + debugInfo.append( "{br} blocks(" ) .append( pmEvent.getBlock() == null ? "0" : "1" ) .append( "+" ) .append( pmEvent.getExplodedBlocks().size() ) @@ -1004,6 +1006,8 @@ else if ( results && pmEvent.getBbPriority().isMonitor() && mine != null ) { } + debugInfo.append( "{br} " ); + return results; } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/block/OnBlockBreakMines.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/block/OnBlockBreakMines.java index 9d297879c..4eb028c6c 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/block/OnBlockBreakMines.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/block/OnBlockBreakMines.java @@ -115,7 +115,7 @@ public String getDebugInfo() { getSpigotBlock().getLocation().toWorldCoordinates(); return String.format( - "AutoFeatures: %s %s %s %s%s ", + "{br} EventInfo: %s %s Mine: %s %s %s ", getResultsReason().name(), // getBbPriority().name(), getSpigotPlayer().getName(), From e234f8c263a754b4a313c8bd23f1627b76d88d64 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sun, 3 Sep 2023 04:54:47 -0400 Subject: [PATCH 088/151] v3.3.0-alpha.15e 2023-09-03 --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 28286d517..e053cfe59 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,7 +3,7 @@ ## # This is actually the "correct" place to define the version for the project. ## # Used within build.gradle with ${project.version}. ## # Can be overridden on the command line: gradle -Pversion=3.2.1-alpha.3 -version=3.3.0-alpha.15d +version=3.3.0-alpha.15e From 48f1bd84e09b9b3614fe7bbadcdc1d8c8ee128b6 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Thu, 7 Sep 2023 09:43:03 -0400 Subject: [PATCH 089/151] 2023-09-03 v3.3.0-alpha.15e --- docs/changelog_v3.3.x.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 147d38ada..1dea66c1a 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -14,9 +14,12 @@ These change logs represent the work that has been going on within prison. -# 3.3.0-alpha.15d 2023-09-03 +# 3.3.0-alpha.15e 2023-09-03 + +**v3.3.0-alpha.15e 2023-09-03** + * **Prison messages: Expanded the use of prison message line breaks, `{br}` in both console messages and sending messages to player.** Auto Features: Added line breaks to the existing block break debug info since it's very long and difficult to read. From 647168891a97ba3a5064097aea65fdf6694aa4e6 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Thu, 7 Sep 2023 09:47:36 -0400 Subject: [PATCH 090/151] Prison logging: When line breaks are applied in log messages, it will no long include the prison template prefix with the message to reduce the clutter and make it easier to read multi-lined content. The line break placeholder is '{br}', similar to the html element BR. --- docs/changelog_v3.3.x.md | 7 ++++++- .../src/main/java/tech/mcprison/prison/output/Output.java | 4 +++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 1dea66c1a..487e01475 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -14,7 +14,12 @@ These change logs represent the work that has been going on within prison. -# 3.3.0-alpha.15e 2023-09-03 +# 3.3.0-alpha.15e 2023-09-07 + + + +* **Prison logging: When line breaks are applied in log messages, it will no long include the prison template prefix with the message to reduce the clutter and make it easier to read multi-lined content.** +The line break placeholder is '{br}', similar to the html element BR. diff --git a/prison-core/src/main/java/tech/mcprison/prison/output/Output.java b/prison-core/src/main/java/tech/mcprison/prison/output/Output.java index c14f77a3c..658e7ab54 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/output/Output.java +++ b/prison-core/src/main/java/tech/mcprison/prison/output/Output.java @@ -282,12 +282,14 @@ else if ( Prison.get() == null || Prison.get().getPlatform() == null ) { // } String msgRaw = String.format(msg, args); + boolean includePrefix = true; for (String msgSplit : msgRaw.split( LINE_SPLITING )) { Prison.get().getPlatform().log( - prefixTemplatePrison + " " + + (includePrefix ? (prefixTemplatePrison + " ") : "") + getLogColorCode(level) + msgSplit); + includePrefix = false; } } From 40c80d28cbff0fa4b11b3d6ee6c2411e980882dc Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Thu, 7 Sep 2023 09:56:48 -0400 Subject: [PATCH 091/151] Ladders: Added a new command to reset all rank costs for a given ladder: '/ranks ladder resetRankCosts help' This will allow a simple and easy change to all rank costs within a given ladder even if there are many ranks, such as the presetiges ladder which could have thousands of ranks. These calculations are similar to how the `/ranks autoConfigure` will set them up. --- docs/changelog_v3.3.x.md | 4 + .../prison/ranks/commands/LadderCommands.java | 101 ++++++++++++++++++ .../prison/ranks/commands/RanksCommands.java | 2 +- 3 files changed, 106 insertions(+), 1 deletion(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 487e01475..e612cb0dc 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -17,6 +17,10 @@ These change logs represent the work that has been going on within prison. # 3.3.0-alpha.15e 2023-09-07 +* **Ladders: Added a new command to reset all rank costs for a given ladder: '/ranks ladder resetRankCosts help'** +This will allow a simple and easy change to all rank costs within a given ladder even if there are many ranks, such as the presetiges ladder which could have thousands of ranks. +These calculations are similar to how the `/ranks autoConfigure` will set them up. + * **Prison logging: When line breaks are applied in log messages, it will no long include the prison template prefix with the message to reduce the clutter and make it easier to read multi-lined content.** The line break placeholder is '{br}', similar to the html element BR. diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/LadderCommands.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/LadderCommands.java index f8d9ab32a..35df70b7f 100644 --- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/LadderCommands.java +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/LadderCommands.java @@ -1,16 +1,20 @@ package tech.mcprison.prison.ranks.commands; import tech.mcprison.prison.Prison; +import tech.mcprison.prison.backups.PrisonBackups; +import tech.mcprison.prison.backups.PrisonBackups.BackupTypes; import tech.mcprison.prison.commands.Arg; import tech.mcprison.prison.commands.Command; import tech.mcprison.prison.internal.CommandSender; import tech.mcprison.prison.output.BulletedListComponent; import tech.mcprison.prison.output.ChatDisplay; +import tech.mcprison.prison.output.Output; import tech.mcprison.prison.ranks.PrisonRanks; import tech.mcprison.prison.ranks.data.PlayerRankRefreshTask; import tech.mcprison.prison.ranks.data.Rank; import tech.mcprison.prison.ranks.data.RankLadder; import tech.mcprison.prison.ranks.managers.LadderManager; +import tech.mcprison.prison.ranks.managers.RankManager; /** * @author Faizaan A. Datoo @@ -483,4 +487,101 @@ public void ladderApplyRankCostMultiplier( CommandSender sender, } + @Command( identifier = "ranks ladder resetRankCosts", + description = "For a given ladder, this command will reset all rank costs. " + + "This allow easier adjustments to many ranks at the same time. " + + "The ranks within this ladder will not be changed, and they will be " + + "processed in the same order in which they are listed with the " + + "command: '/ranks list '.", + onlyPlayers = false, permissions = "ranks.ladder" ) + public void ladderResetRankCosts(CommandSender sender, + @Arg(name = "ladderName") String ladderName, + + @Arg(name = "initialCost", + def = "1000000000", verifiers = "min[1]", + description = "The 'initialCost' will set the cost of the first rank on " + + "this ladder. All other rank costs will be based upon this " + + "value. The default value is 1_000_000_0000." + ) double initialCost, + @Arg(name = "addMult", def = "1", verifiers = "min[1]", + description = "This is an 'additional multiplier' for all ranks on the ladder, " + + "with the default value of 1. The cost for each rank is based upon " + + "the initial rank cost, times the rank's level. So the default ranks " + + "named 'C', or 'p3', since both are the third rank on their ladders, " + + "will be 3 times the cost of the first ranks, 'A' or 'p1', with this " + + "additional multiplier being multiplied against that value. " + + "So for default values for a rankk in the third position, " + + "with a 1.75 multipler will have a " + + "cost = 1_000_000_000 * 3 * 1.75.") double addMult ) { + + + LadderManager lm = PrisonRanks.getInstance().getLadderManager(); + RankManager rm = PrisonRanks.getInstance().getRankManager(); + + RankLadder ladder = lm.getLadder(ladderName); + + if ( ladder == null ) { + ladderDoesNotExistsMsg( sender, ladderName ); + return; + } + + // Force a backup: + PrisonBackups prisonBackup = new PrisonBackups(); + + String backupComment = String.format( + "Resetting all rank costs on ladder %s.", + ladder.getName() ); + String message = prisonBackup.startBackup( BackupTypes.auto, backupComment ); + + sender.sendMessage( message ); + sender.sendMessage( "Forced a Backup of prison configs prior to changing rank costs." ); + + + int ranksChanged = 0; + + int i = 0; + for (Rank rank : ladder.getRanks() ) { + + double cost = initialCost * (i++ + 1) * addMult; + + if ( rank.getRawRankCost() != cost ) { + rank.setRawRankCost( cost ); + + rm.saveRank( rank ); + + ranksChanged++; + } + + } + + if ( ranksChanged > 0 ) { + // Reload the placeholders: + Prison.get().getPlatform().getPlaceholders().reloadPlaceholders(); + + String msg = String.format( + "Done resetting all rank costs on the '%s' ladder. " + + "There were %d ranks that had cost changes.", + ladder.getName(), + ranksChanged ); + + Output.get().logInfo( msg ); + } + +// for ( int i = 0; i < prestigeRanks; i++ ) { +// String name = "P" + (i + 1); +// String tag = "&5[&d+" + (i > 0 ? i + 1 : "" ) + "&5]"; +// double cost = prestigeCost * (i + 1) * prestigeMult; +// +// // Only add prestige ranks if they do not already exist: +// if ( PrisonRanks.getInstance().getRankManager().getRank( name ) == null ) { +// +// createRank(sender, name, cost, LadderManager.LADDER_PRESTIGES, tag, "noPlaceholderUpdate"); +// prestigesCount++; +// } +// } + + + } + + } diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/RanksCommands.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/RanksCommands.java index df269b9a5..eec9703b2 100644 --- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/RanksCommands.java +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/RanksCommands.java @@ -230,7 +230,7 @@ public boolean createRank(CommandSender sender, "So using just 'mines' will only generate mines and no ranks or prestiges." + "The option 'prestiges=x' will set how many initial prestige ranks to create. " + - "The option `prestigeCost=x` sets the intial cost for P1; default value is 1_000_000_000. " + + "The option `prestigeCost=x` sets the initial cost for P1; default value is 1_000_000_000. " + "The option 'prestigeMult=x' is an additional multiplier for presetige ranks, with the " + "default value of 1. The cost for each prestige rank is based upon the initial " + "presetigeCost, times the prestige level so p3 will be 3 times the cost of p1 with the " + From 9a6d3e3cb9b4cdc93fa0c1704b7d85d6b09d6a7b Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 9 Sep 2023 13:12:35 -0400 Subject: [PATCH 092/151] Update the rank's getPosition() java docs to better clarify what it is. --- docs/changelog_v3.3.x.md | 5 ++++- .../java/tech/mcprison/prison/ranks/data/Rank.java | 11 ++++++++--- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index e612cb0dc..51ae1ec9a 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -14,7 +14,10 @@ These change logs represent the work that has been going on within prison. -# 3.3.0-alpha.15e 2023-09-07 +# 3.3.0-alpha.15e 2023-09-09 + + +* **Update the rank's getPosition() java docs to better clarify what it is.** * **Ladders: Added a new command to reset all rank costs for a given ladder: '/ranks ladder resetRankCosts help'** diff --git a/prison-core/src/main/java/tech/mcprison/prison/ranks/data/Rank.java b/prison-core/src/main/java/tech/mcprison/prison/ranks/data/Rank.java index 976e61da9..007d2fd87 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/ranks/data/Rank.java +++ b/prison-core/src/main/java/tech/mcprison/prison/ranks/data/Rank.java @@ -403,10 +403,15 @@ public int compareTo( Rank r ) } /** - * This new implementation of position is lazy loaded and should never be saved. - * This is to provide a quick reference to the position within the ladder's rank's - * ArrayList. This should never be used to access a rank or to refer to a rank; the + *

This provides a quick reference to the position within the ladder's rank's + * ArrayList. This value is zero based, where the first rank on the ladders has + * a position of 0. + *

+ * + *

This new implementation of position is lazy loaded and should never be saved. + * This should never be used to access a rank or to refer to a rank; the * actual objects should be used for that. + *

* * @return */ From c37e316bf1eaf528eb19f545723dd97f6498ec61 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 9 Sep 2023 13:20:04 -0400 Subject: [PATCH 093/151] Ranks Auto Configure: Fixed message format when options are not valid so it's better understood what's wrong with the command. The parameter names are case sensitive, but added a fallback mapping to lowercase so there is a higher chance of matching the correct commands. Had to move the location of the 'prestigeMulti=' parameter to be evaluated before 'multi=' parameter since it was taking over the `prestigeMulti=` parameter. --- docs/changelog_v3.3.x.md | 5 +++++ prison-core/src/main/resources/lang/ranks/en_US.properties | 6 ++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 51ae1ec9a..43511265b 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -17,6 +17,11 @@ These change logs represent the work that has been going on within prison. # 3.3.0-alpha.15e 2023-09-09 +* **Ranks Auto Configure: Fixed message format when options are not valid so it's better understood what's wrong with the command.** +The parameter names are case sensitive, but added a fallback mapping to lowercase so there is a higher chance of matching the correct commands. +Had to move the location of the 'prestigeMulti=' parameter to be evaluated before 'multi=' parameter since it was taking over the `prestigeMulti=` parameter. + + * **Update the rank's getPosition() java docs to better clarify what it is.** diff --git a/prison-core/src/main/resources/lang/ranks/en_US.properties b/prison-core/src/main/resources/lang/ranks/en_US.properties index 5e5718ab2..8d0fc484d 100644 --- a/prison-core/src/main/resources/lang/ranks/en_US.properties +++ b/prison-core/src/main/resources/lang/ranks/en_US.properties @@ -58,8 +58,10 @@ # these are a very low level static component of the fallback messaging system within Prison. # You will have to restart the server if you make any changes to the messages with these prefixes. # +# NOTE: You can add line feeds to your messages by inserting the placeholder '{br}'. +# -messages__version=28 +messages__version=29 messages__auto_refresh=true ranks_rankup__rankup_no_player_name=You have @@ -259,7 +261,7 @@ ranks_rankCommands__error_writting_ladder=&3The '&7%1&3' ladder could not be sav ranks_rankCommands__auto_config_preexisting_warning=&3You are trying to run &7/ranks autoConfigure&3 with ranks or mines already setup. Rank count = &7%1&3. Mine count = &7%2&3. Please run this command with the &7help&3 keyword for more information and other customization options: &7/ranks autoConfigure help&3. It's best to run this command from the &7console&3 due to the volume of data it generates. Add the option '&7force&3' to force this process to run. If there is a conflict with a preexisting rank or mine, this process will do it's best to merge the new ranks and mines with what already exist. There is the risk something may not merge correctly. When merging, all blocks will be replaced, but in the console the original block list will be printed for reference if you want to recreate them. Please backup your &7plugins/Prison/&3 directory before running to be safe. ranks_rankCommands__auto_config_force_warning=&aWarning! &3Running autoConfigure with &7force&3 enabled. Not responsible if mines or ranks collide. -ranks_rankCommands__auto_config_invalid_options=&3Invalid options. Use %1&3. Was: &3%2 +ranks_rankCommands__auto_config_invalid_options=&3Invalid options detected. {br}Use %1&3. {br}&3The unknown remaining options were: [&7%2&3] ranks_rankCommands__auto_config_skip_rank_warning=&aWarning! &3Rank &7%1 &3already exists and is being skipped along with generating the mine if enabled, along with all of the other features. ranks_rankCommands__auto_config_no_ranks_created=Ranks autoConfigure: No ranks were created. From 13acfd1983c7c52ab0d272b1f2955e65b7fa0f60 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 9 Sep 2023 13:24:53 -0400 Subject: [PATCH 094/151] SellAll multipliers: Increased the number of columns for the listing to 8 columns instead of 5. May need to expand it even more so if there are thousands of ranks, it can be better managed. New command: `/sellall multiplier deleteLadder` deletes all multipliers for that ladder. New command: `/sellall multiplier addLadder` adds multipliers for all ranks on the ladder. --- .../commands/PrisonSpigotSellAllCommands.java | 149 +++++++++++++++++- 1 file changed, 148 insertions(+), 1 deletion(-) diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/commands/PrisonSpigotSellAllCommands.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/commands/PrisonSpigotSellAllCommands.java index 89b8a8342..72a618773 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/commands/PrisonSpigotSellAllCommands.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/commands/PrisonSpigotSellAllCommands.java @@ -20,6 +20,10 @@ import tech.mcprison.prison.internal.block.PrisonBlock; import tech.mcprison.prison.output.ChatDisplay; import tech.mcprison.prison.output.Output; +import tech.mcprison.prison.ranks.PrisonRanks; +import tech.mcprison.prison.ranks.data.Rank; +import tech.mcprison.prison.ranks.data.RankLadder; +import tech.mcprison.prison.ranks.managers.RankManager; import tech.mcprison.prison.sellall.messages.SpigotVariousGuiMessages; import tech.mcprison.prison.spigot.SpigotPlatform; import tech.mcprison.prison.spigot.SpigotPrison; @@ -904,7 +908,7 @@ private void sellAllMultiplierCommand(CommandSender sender){ // sb.append( String.format( "%-" + maxLenKey + "s %" + maxLenVal + "s %-" + maxLenCode + "s", // key.toString(), fFmt.format( cost ), key.name() ) ); - if ( columns > 4 ) { + if ( columns > 7 ) { chatDisplay.addText( sb.toString() ); if ( ++lines % 10 == 0 && lines > 1 ) { @@ -1004,6 +1008,149 @@ private void sellAllDeleteMultiplierCommand(CommandSender sender, Output.get().sendInfo(sender, messages.getString(MessagesConfig.StringID.spigot_message_sellall_multiplier_delete_success)); } } + + + + + @Command(identifier = "sellall multiplier deleteLadder", + description = "Deletes all SellAll Rank multipliers for a ladder.", + permissions = "prison.admin", onlyPlayers = false) + private void sellAllMultiplierDeleteLadderCommand( + CommandSender sender, + @Arg(name = "ladder", + description = "All ranks with multipliers for this ladder will be removed.") String ladderName + + ) { + + if (!isEnabled()) return; + + SellAllUtil sellAllUtil = SellAllUtil.get(); + if (sellAllUtil == null){ + return; + } + + if (!sellAllUtil.isSellAllMultiplierEnabled){ + Output.get().sendWarn(sender, messages.getString(MessagesConfig.StringID.spigot_message_sellall_multiplier_are_disabled)); + return; + } + + if ( !PrisonRanks.getInstance().isEnabled() ) { + Output.get().sendWarn(sender, "Cannot use command `/sellall multiplier deleteLadder` since ranks are disabled" ); + return; + } + + RankLadder ladder = PrisonRanks.getInstance().getLadderManager().getLadder(ladderName); + + + if ( ladder == null ) { + Output.get().sendWarn(sender, + "A ladder with the name of '%s' does not exist. Use '/ranks ladder list' " + + "to find the correct ladder name.", ladderName ); + + return; + } + + DecimalFormat iFmt = Prison.get().getDecimalFormat("#,##0"); + + int removed = 0; + for (Rank rank : ladder.getRanks() ) { + + if (sellAllUtil.removeSellallRankMultiplier( rank.getName() )) { + removed++; + } + } + + sender.sendMessage( + String.format( + "For ladder %s, there were %s multipliers removed.", + ladderName, iFmt.format(removed)) ); + + } + + + + @Command(identifier = "sellall multiplier addLadder", + description = "Adds multipliers for all ranks on the ladder. " + + "If they already exist, they will be replaced. The formula used to " + + "calculate the multiplier is " + + "'multiplier = baseMultiplier + ((rankPosition - 1) * rankMultiplier)'.", + permissions = "prison.admin", onlyPlayers = false) + private void sellAllMultiplierAddLadderCommand( + CommandSender sender, + @Arg(name = "ladder", + description = "Add multipliers for all ranks on this ladder. " + + "If multipliers already exist, they will be replaced.") + String ladderName, + @Arg(name = "baseMultiplier", + description = "The baseMultiplier that will have the rank's " + + "position multiplier added to it.") + double baseMultiplier, + @Arg(name = "rankMultiplier", + description = "The multiplier applied to the rank position.") + double rankMultiplier + + ) { + + if (!isEnabled()) return; + + SellAllUtil sellAllUtil = SellAllUtil.get(); + if (sellAllUtil == null){ + return; + } + + if (!sellAllUtil.isSellAllMultiplierEnabled){ + Output.get().sendWarn(sender, messages.getString(MessagesConfig.StringID.spigot_message_sellall_multiplier_are_disabled)); + return; + } + + if ( !PrisonRanks.getInstance().isEnabled() ) { + Output.get().sendWarn(sender, "Cannot use command `/sellall multiplier addLadder` since ranks are disabled" ); + return; + } + + RankLadder ladder = PrisonRanks.getInstance().getLadderManager().getLadder(ladderName); + + + if ( ladder == null ) { + Output.get().sendWarn(sender, + "A ladder with the name of '%s' does not exist. Use '/ranks ladder list' " + + "to find the correct ladder name.", ladderName ); + + return; + } + + DecimalFormat iFmt = Prison.get().getDecimalFormat("#,##0"); + + int added = 0; + int failed = 0; + for (Rank rank : ladder.getRanks() ) { + + int rankPos = rank.getPosition(); + + double multi = baseMultiplier + (rankPos * rankMultiplier); + + if ( sellAllUtil.addSellallRankMultiplier(rank.getName(), multi) ) { + // No message should be sent for each rank, since there could be thousands of prestige ranks + added++; + } + else { + failed++; + } + + } + + sender.sendMessage( + String.format( + "For ladder %s, there were %s multipliers added, and %s failed to be added.", + ladderName, + iFmt.format(added), + iFmt.format(failed) + ) ); + + } + + + @Command(identifier = "sellall set trigger", description = "Toggle SellAll trigger to enable/disable the Shift+Right Clicking " From 55343874e970fbe3c87a8c25d47009b6c54b8eb5 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 9 Sep 2023 13:29:36 -0400 Subject: [PATCH 095/151] Commit the changelog for the sellall multipliers. --- docs/changelog_v3.3.x.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 43511265b..c08f040b5 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -17,6 +17,11 @@ These change logs represent the work that has been going on within prison. # 3.3.0-alpha.15e 2023-09-09 +* **SellAll multipliers: Increased the number of columns for the listing to 8 columns instead of 5.** May need to expand it even more so if there are thousands of ranks, it can be better managed. +New command: `/sellall multiplier deleteLadder` deletes all multipliers for that ladder. +New command: `/sellall multiplier addLadder` adds multipliers for all ranks on the ladder. + + * **Ranks Auto Configure: Fixed message format when options are not valid so it's better understood what's wrong with the command.** The parameter names are case sensitive, but added a fallback mapping to lowercase so there is a higher chance of matching the correct commands. Had to move the location of the 'prestigeMulti=' parameter to be evaluated before 'multi=' parameter since it was taking over the `prestigeMulti=` parameter. From 53bf7a92be9d9b571a72d106c58dc74ea093b3e7 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 9 Sep 2023 14:05:12 -0400 Subject: [PATCH 096/151] sellall multiplier addLadder: added more comments to the command's help, and added defaults to the parameters. --- docs/changelog_v3.3.x.md | 3 +++ .../spigot/commands/PrisonSpigotSellAllCommands.java | 9 +++++++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index c08f040b5..970311763 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -17,6 +17,9 @@ These change logs represent the work that has been going on within prison. # 3.3.0-alpha.15e 2023-09-09 +* **sellall multiplier addLadder: added more comments to the command's help, and added defaults to the parameters.** + + * **SellAll multipliers: Increased the number of columns for the listing to 8 columns instead of 5.** May need to expand it even more so if there are thousands of ranks, it can be better managed. New command: `/sellall multiplier deleteLadder` deletes all multipliers for that ladder. New command: `/sellall multiplier addLadder` adds multipliers for all ranks on the ladder. diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/commands/PrisonSpigotSellAllCommands.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/commands/PrisonSpigotSellAllCommands.java index 72a618773..697322d7f 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/commands/PrisonSpigotSellAllCommands.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/commands/PrisonSpigotSellAllCommands.java @@ -1073,19 +1073,24 @@ private void sellAllMultiplierDeleteLadderCommand( description = "Adds multipliers for all ranks on the ladder. " + "If they already exist, they will be replaced. The formula used to " + "calculate the multiplier is " - + "'multiplier = baseMultiplier + ((rankPosition - 1) * rankMultiplier)'.", + + "'multiplier = baseMultiplier + ((rankPosition - 1) * rankMultiplier)'. " + + "Example: '/sellall multiplier addLadder presetiges 1.0 0.1' will result in " + + "p1=1.0 p2=1.1 p3=1.2 p4=1.3 etc...", permissions = "prison.admin", onlyPlayers = false) private void sellAllMultiplierAddLadderCommand( CommandSender sender, - @Arg(name = "ladder", + @Arg(name = "ladder", + def = "prestiges", description = "Add multipliers for all ranks on this ladder. " + "If multipliers already exist, they will be replaced.") String ladderName, @Arg(name = "baseMultiplier", + def = "1.0", description = "The baseMultiplier that will have the rank's " + "position multiplier added to it.") double baseMultiplier, @Arg(name = "rankMultiplier", + def = "0.1", description = "The multiplier applied to the rank position.") double rankMultiplier From 03aac10572ffa9af26c669b126b52a96b73d8b4d Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 9 Sep 2023 14:11:37 -0400 Subject: [PATCH 097/151] sellall multiplier list: Now applies a sort order to the ranks. It groups by ladders, and then lists the ranks in rank order, within each ladder. --- docs/changelog_v3.3.x.md | 3 + .../commands/PrisonSpigotSellAllCommands.java | 124 +++++++++++++----- 2 files changed, 93 insertions(+), 34 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 970311763..967ee45f9 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -17,6 +17,9 @@ These change logs represent the work that has been going on within prison. # 3.3.0-alpha.15e 2023-09-09 +* **sellall multiplier list: Now applies a sort order to the ranks, grouping by ladders.** It groups by ladders, and then lists the ranks in rank order, within each ladder. + + * **sellall multiplier addLadder: added more comments to the command's help, and added defaults to the parameters.** diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/commands/PrisonSpigotSellAllCommands.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/commands/PrisonSpigotSellAllCommands.java index 697322d7f..0a4967b1c 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/commands/PrisonSpigotSellAllCommands.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/commands/PrisonSpigotSellAllCommands.java @@ -2,6 +2,7 @@ import java.text.DecimalFormat; import java.util.ArrayList; +import java.util.List; import java.util.Set; import java.util.TreeMap; @@ -23,15 +24,12 @@ import tech.mcprison.prison.ranks.PrisonRanks; import tech.mcprison.prison.ranks.data.Rank; import tech.mcprison.prison.ranks.data.RankLadder; -import tech.mcprison.prison.ranks.managers.RankManager; -import tech.mcprison.prison.sellall.messages.SpigotVariousGuiMessages; import tech.mcprison.prison.spigot.SpigotPlatform; import tech.mcprison.prison.spigot.SpigotPrison; import tech.mcprison.prison.spigot.block.SpigotItemStack; import tech.mcprison.prison.spigot.compat.Compatibility; import tech.mcprison.prison.spigot.configs.MessagesConfig; import tech.mcprison.prison.spigot.game.SpigotPlayer; -import tech.mcprison.prison.spigot.gui.sellall.SellAllAdminBlocksGUI; import tech.mcprison.prison.spigot.sellall.SellAllBlockData; import tech.mcprison.prison.spigot.sellall.SellAllUtil; import tech.mcprison.prison.spigot.utils.tasks.PlayerAutoRankupTask; @@ -848,6 +846,7 @@ private void sellAllEditCommand(CommandSender sender, } } + @Command(identifier = "sellall multiplier list", description = "Lists all of the SellAll Rank multipliers", permissions = "prison.admin", onlyPlayers = false) @@ -865,6 +864,15 @@ private void sellAllMultiplierCommand(CommandSender sender){ return; } + + if ( !PrisonRanks.getInstance().isEnabled() ) { + Output.get().sendWarn(sender, "Cannot use command `/sellall multiplier addLadder` since ranks are disabled" ); + return; + } + + List ladders = PrisonRanks.getInstance().getLadderManager().getLadders(); + + // String registeredCmd = Prison.get().getCommandHandler().findRegisteredCommand( "sellall multiplier help" ); // sender.dispatchCommand(registeredCmd); @@ -872,56 +880,104 @@ private void sellAllMultiplierCommand(CommandSender sender){ TreeMap mults = new TreeMap<>( sellAllUtil.getPrestigeMultipliers() ); // TreeMap items = new TreeMap<>( sellAllUtil.getSellAllBlocks() ); - DecimalFormat fFmt = Prison.get().getDecimalFormat("#,##0.00"); + DecimalFormat dFmt = Prison.get().getDecimalFormat("#,##0.00"); + DecimalFormat iFmt = Prison.get().getDecimalFormat("#,##0"); Set keys = mults.keySet(); + // Need to calculate the maxLenVal so we can properly space all columns: int maxLenKey = 0; int maxLenVal = 0; for ( String key : keys ) { if ( key.length() > maxLenKey ) { maxLenKey = key.length(); } - String val = fFmt.format( mults.get( key ) ); + String val = dFmt.format( mults.get( key ) ); if ( val.length() > maxLenVal ) { maxLenVal = val.length(); } } + String multiplierLayout = "%-" + maxLenKey + "s %" + maxLenVal + "s"; ChatDisplay chatDisplay = new ChatDisplay("&bSellall Rank Multipliers list: &3(&b" + keys.size() + "&3)" ); - int lines = 0; - int columns = 0; - StringBuilder sb = new StringBuilder(); - for ( String key : keys ) { -// boolean first = sb.length() == 0; - Double cost = mults.get( key ); - - if ( columns++ > 0 ) { - sb.append( " " ); - } - - sb.append( String.format( "%-" + maxLenKey + "s %" + maxLenVal + "s", - key, fFmt.format( cost ) ) ); -// sb.append( String.format( "%-" + maxLenKey + "s %" + maxLenVal + "s %-" + maxLenCode + "s", -// key.toString(), fFmt.format( cost ), key.name() ) ); - - if ( columns > 7 ) { - chatDisplay.addText( sb.toString() ); - - if ( ++lines % 10 == 0 && lines > 1 ) { - chatDisplay.addText( " " ); - } + for (RankLadder ladder : ladders ) { + + StringBuilder sb = new StringBuilder(); + + int lines = 0; + int columns = 0; + for ( Rank rank : ladder.getRanks() ) { + String key = rank.getName(); - sb.setLength( 0 ); - columns = 0; - } - } - if ( sb.length() > 0 ) { - chatDisplay.addText( sb.toString() ); - } + if ( mults.containsKey( key ) ) { + + if ( lines == 0 && sb.length() == 0 ) { + chatDisplay.addText( "&3Ladder: &7%s &3Ranks: &7%s", + ladder.getName(), + iFmt.format( ladder.getRanks().size() )); + } + + Double cost = mults.get( key ); + + if ( columns++ > 0 ) { + sb.append( " " ); + } + + sb.append( String.format( multiplierLayout, + key, dFmt.format( cost ) ) ); + + if ( columns > 9 ) { + chatDisplay.addText( sb.toString() ); + + if ( ++lines % 10 == 0 && lines > 1 ) { + chatDisplay.addText( " " ); + } + + sb.setLength( 0 ); + columns = 0; + } + + } + } + if ( sb.length() > 0 ) { + chatDisplay.addText( sb.toString() ); + } + + } + + +// int columns = 0; +// for ( String key : keys ) { +//// boolean first = sb.length() == 0; +// +// Double cost = mults.get( key ); +// +// if ( columns++ > 0 ) { +// sb.append( " " ); +// } +// +// sb.append( String.format( "%-" + maxLenKey + "s %" + maxLenVal + "s", +// key, fFmt.format( cost ) ) ); +//// sb.append( String.format( "%-" + maxLenKey + "s %" + maxLenVal + "s %-" + maxLenCode + "s", +//// key.toString(), fFmt.format( cost ), key.name() ) ); +// +// if ( columns > 7 ) { +// chatDisplay.addText( sb.toString() ); +// +// if ( ++lines % 10 == 0 && lines > 1 ) { +// chatDisplay.addText( " " ); +// } +// +// sb.setLength( 0 ); +// columns = 0; +// } +// } +// if ( sb.length() > 0 ) { +// chatDisplay.addText( sb.toString() ); +// } chatDisplay.send( sender ); From 14d31c5c05fa5fc5c89ab428e03e5d51b82669b8 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 9 Sep 2023 14:13:28 -0400 Subject: [PATCH 098/151] Ranks Auto Configure: Fixed message format when options are not valid so it's better understood what's wrong with the command. The parameter names are case sensitive, but added a fallback mapping to lowercase so there is a higher chance of matching the correct commands. Had to move the location of the 'prestigeMulti=' parameter to be evaluated before 'multi=' parameter since it was taking over the `prestigeMulti=` parameter. --- .../prison/ranks/commands/RanksCommands.java | 35 ++++++++++++------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/RanksCommands.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/RanksCommands.java index eec9703b2..f29f50f94 100644 --- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/RanksCommands.java +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/RanksCommands.java @@ -349,6 +349,20 @@ public void autoConfigureRanks(CommandSender sender, } + String prestigeMultStr = extractParameter("prestigeMult=", options); + if ( prestigeMultStr != null ) { + options = options.replace( prestigeMultStr, "" ); + prestigeMultStr = prestigeMultStr.replace( "prestigeMult=", "" ).trim(); + + try { + prestigeMult = Double.parseDouble( prestigeMultStr ); + } + catch ( NumberFormatException e ) { + // Not a valid double number, or price: + } + } + + String multStr = extractParameter("mult=", options); if ( multStr != null ) { options = options.replace( multStr, "" ); @@ -387,19 +401,7 @@ public void autoConfigureRanks(CommandSender sender, // Not a valid double number, or price: } } - - String prestigeMultStr = extractParameter("prestigeMult=", options); - if ( prestigeMultStr != null ) { - options = options.replace( prestigeMultStr, "" ); - prestigeMultStr = prestigeMultStr.replace( "prestigeMult=", "" ).trim(); - - try { - prestigeMult = Double.parseDouble( prestigeMultStr ); - } - catch ( NumberFormatException e ) { - // Not a valid double number, or price: - } - } + // This has to be checked after prestiges= or this will destroy that config setting: if ( options.contains( "prestiges" ) ) { @@ -675,6 +677,9 @@ public void autoConfigureRanks(CommandSender sender, } private String extractParameter( String key, String options ) { + return extractParameter( key, options, true ); + } + private String extractParameter( String key, String options, boolean tryLowerCase ) { String results = null; int idx = options.indexOf( key ); if ( idx != -1 ) { @@ -684,6 +689,10 @@ private String extractParameter( String key, String options ) { } results = options.substring( idx, idxEnd ); } + else if ( tryLowerCase ) { + // try again, but lowercase the key + results = extractParameter( key.toLowerCase(), options, false ); + } return results; } From dd2aeb045530e117008f7cffc1f1156b62ad062e Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 9 Sep 2023 20:21:05 -0400 Subject: [PATCH 099/151] sellall multipliers list: Added 2 options to control the number of columns displayed with 'cols=7' and also only show multipliers for a single ladder if that ladder name is provided in the options. --- docs/changelog_v3.3.x.md | 3 + .../commands/PrisonSpigotSellAllCommands.java | 68 +++++++++++++++++-- 2 files changed, 65 insertions(+), 6 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 967ee45f9..6dd719ccb 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -17,6 +17,9 @@ These change logs represent the work that has been going on within prison. # 3.3.0-alpha.15e 2023-09-09 +* **sellall multipliers list: Added 2 options to control the number of columns displayed with 'cols=7' and also only show multipliers for a single ladder if that ladder name is provided in the options.** + + * **sellall multiplier list: Now applies a sort order to the ranks, grouping by ladders.** It groups by ladders, and then lists the ranks in rank order, within each ladder. diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/commands/PrisonSpigotSellAllCommands.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/commands/PrisonSpigotSellAllCommands.java index 0a4967b1c..3592afc3b 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/commands/PrisonSpigotSellAllCommands.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/commands/PrisonSpigotSellAllCommands.java @@ -850,7 +850,13 @@ private void sellAllEditCommand(CommandSender sender, @Command(identifier = "sellall multiplier list", description = "Lists all of the SellAll Rank multipliers", permissions = "prison.admin", onlyPlayers = false) - private void sellAllMultiplierCommand(CommandSender sender){ + private void sellAllMultiplierCommand(CommandSender sender, + @Wildcard(join=true) + @Arg(name = "options", + description = "Optionaly, you can control which ladder is displayed. By default, it's " + + "all ladders. Just use the ladder's name. You can also change the number of " + + "columns in the output by using 'cols=16', where the default is 10 columns. ") + String options ) { if (!isEnabled()) return; @@ -870,7 +876,41 @@ private void sellAllMultiplierCommand(CommandSender sender){ return; } - List ladders = PrisonRanks.getInstance().getLadderManager().getLadders(); + int displayColumns = 10; + String ladderName = ""; + RankLadder rLadder = null; + + + // pull columns out of the options, if it has been specified: + String colsStr = extractParameter("cols=", options); + if ( colsStr != null ) { + options = options.replace( colsStr, "" ).trim(); + colsStr = colsStr.replace( "cols=", "" ).trim(); + + try { + displayColumns = Integer.parseInt( colsStr ); + } + catch ( NumberFormatException e ) { + // Not a valid int number: + } + } + + + // Check to see if the remaining options is a ladder name, if so, then only load that ladder: + if ( options.length() > 0 ) { + rLadder = PrisonRanks.getInstance().getLadderManager().getLadder( options ); + } + + + List ladders = new ArrayList<>(); + + if ( rLadder == null ) { + ladders = PrisonRanks.getInstance().getLadderManager().getLadders(); + } + else { + ladders.add( rLadder ); + } + @@ -929,7 +969,7 @@ private void sellAllMultiplierCommand(CommandSender sender){ sb.append( String.format( multiplierLayout, key, dFmt.format( cost ) ) ); - if ( columns > 9 ) { + if ( columns >= displayColumns ) { chatDisplay.addText( sb.toString() ); if ( ++lines % 10 == 0 && lines > 1 ) { @@ -981,11 +1021,27 @@ private void sellAllMultiplierCommand(CommandSender sender){ chatDisplay.send( sender ); - - - } + private String extractParameter( String key, String options ) { + return extractParameter( key, options, true ); + } + private String extractParameter( String key, String options, boolean tryLowerCase ) { + String results = null; + int idx = options.indexOf( key ); + if ( idx != -1 ) { + int idxEnd = options.indexOf( " ", idx ); + if ( idxEnd == -1 ) { + idxEnd = options.length(); + } + results = options.substring( idx, idxEnd ); + } + else if ( tryLowerCase ) { + // try again, but lowercase the key + results = extractParameter( key.toLowerCase(), options, false ); + } + return results; + } @Command(identifier = "sellall multiplier add", description = "Add a sellall multiplier based upon the player's rank. " + From d1460ea0ca75b97a4cec336320f776e09cdd9ebe Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 9 Sep 2023 20:22:49 -0400 Subject: [PATCH 100/151] Update docs and some command descriptions to make them a little more clearer as to what they do. --- docs/changelog_v3.3.x.md | 3 + ...ison_docs_100_setting_up_auto_configure.md | 44 ++++++++++++-- .../prison/ranks/commands/LadderCommands.java | 58 +++++++++++++++---- .../prison/ranks/commands/RanksCommands.java | 15 +++-- 4 files changed, 96 insertions(+), 24 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 6dd719ccb..93b22cc87 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -17,6 +17,9 @@ These change logs represent the work that has been going on within prison. # 3.3.0-alpha.15e 2023-09-09 +* **Update docs and some command descriptions to make them a little more clearer as to what they do.** + + * **sellall multipliers list: Added 2 options to control the number of columns displayed with 'cols=7' and also only show multipliers for a single ladder if that ladder name is provided in the options.** diff --git a/docs/prison_docs_100_setting_up_auto_configure.md b/docs/prison_docs_100_setting_up_auto_configure.md index e267ba0ed..9e5fc2b5b 100644 --- a/docs/prison_docs_100_setting_up_auto_configure.md +++ b/docs/prison_docs_100_setting_up_auto_configure.md @@ -10,7 +10,7 @@ This document provides information on how to get started quickly using Prison's [Prison Log File Examples - Starting Prison & auto configure](prison_docs_101_auto_configure_log_examples.md) -*Documented updated: 2021-12-11* +*Documented updated: 2023-09-09*
@@ -19,6 +19,10 @@ This document provides information on how to get started quickly using Prison's This document covers how to run `/ranks autoConfigure`, it's options, and what to do after the command runs. +It is strongly suggested to run this command and read the current help documentation for the command because a lot of changes have been happening to the commands, but these documents may be out of date: +`/ranks autoConfigure help` + + Prison's Auto Configure will perform most of the basic configurations to get you up and running quickly. This feature will perform the following tasks for you: @@ -38,7 +42,7 @@ Prison's Auto Configure will perform most of the basic configurations to get you * Auto assign random Mine Liners to each mine. -* Auto generate 10 Prestige Ranks and have them enabled by default. +* Auto generate 25 Prestige Ranks and have them enabled by default. * Enable Ladder Base Rank Cost Multiplier for the Prestiges ladder. Once a player prestiges, this will enable a rank cost multiplier that will increase all rank cost. As the player ranks upon the prestiges ladder, the rank costs will increase. @@ -311,13 +315,40 @@ Generally you would never need to use any of the options. But they do provide f * **mult=x** - The default value for the multiplier is 1.5. This is the multiplier that is used calculate the next rank. So if the first rank has an initial cost of 50,000 then the second rank cost is 1.5 times that value. Therefore the second rank will have a cost of 75,000 (50,000 * 1.5). -* **Force** - If any mines or ranks exist, normally it will prevent auto configure from running. **Force** forces it to run, but with consequences. It will skip over any rank or mine that it would otherwise try to generate. It will not add rank commands to existing ranks. It will not add blocks to existing mines. It will not hook up ranks to mines. Nor will it configure such features as Mine Access Permissions. If you decide to use **force** you do so at your own risks. +* **Force** - If any mines or ranks exist, normally it will prevent auto configure from running. **Force** forces it to run, but with consequences. Auto configure will try to merge any preexisting ranks and mines, but it will also replace all blocks in all mines. There maybe some unexpected consequences to forcing an auto configure, so back up your data. If you decide to use **force** you do so at your own risks. + + +* **forceKeepBlocks** - If forcing auto configure to run again, the 'forceKeepBlocks' will prevent existing mines from having their blocks reset to the defaults. + + +* **ranks** - If specified, it will only generate ranks and not the mines or prestigies. + + +* **mines** - If specified, it will only generate mines and not the ranks or prestiges. + +* **prestiges** - If specified, it will only generate prestiges and not the mines or ranks. + + +* **prestiges=x** - Will set how many initial prestige ranks to create. + +* **prestigeCost=x** - Sets the initial cost for P1; default value is 1_000_000_000. + +* **prestigeMult=x** - Is an additional multiplier for presetige ranks, with the default value of 1. The cost for each prestige rank is based upon the initial presetigeCost, times the prestige level so p3 will be 3 times the cost of p1 with the prestige multiplier will multiplied against that value. So for default values with a 1.75 multiplier p3 cost = 1_000_000_000 * 3 * 1.75. Default values [full price=50000 mult=1.5 prestiges=25 presetigeCost=1000000000 prestigeMult=1] + +* NOTE: Use of these parameters, you can adjust some of the settings on your server, without replacing preexisting configurations. + + +Other commands of interest: +* `/ranks ladder rankCostMultiplier help' - Is used to calculate a player's rank cost when they rankup. This is a multiplier based up a ladder, where the ladder's multiplier is multiplied by that ladder's position. So if a prestige ladder uses a rank cost multiplier of 0.1 (10 percent), then when a player is at P0 (no presetige rank) it will not increase the costs of the default ranks prices. But when they are at P1, then it will be a 10% increase, and at p10 it will be at a 100% increase (twice as expensive than p0). A ladder could be set to zero so it does not contribute to the player's total calculated rank cost multipliers. -* **ranks** - If specified, it will only generate ranks and not the mines. +* `/ranks ladder applyRankCostMultiplier help' - This is a ladder setting where if a ladder applies the player's rank cost multiplier then it's rankup costs on it's ladder will apply the rank cost multiplier. If the ladder is disabled, then it will use the raw rank cost. Note a ladder can be disabled, but yet still contribute to the players total rank cost multiplier. +* `/ranks ladder resetRankCosts help' - This resets all rank costs on a ladder based upon a uniform formula. This is good to use after adding new ranks, and you want each rank to be progressivly more expensive, at a uniform rate. -* **mines** - If specified, it will only generate mines and not the ranks. +* '/sellall multiplier addLadder help' - Adds one multiplier per rank for a given ladder. You can control how the multiplier is generated per rank. +* '/sellall multiplier deleteLadder help' - Deletes all multipliers for a given ladder. This is very useful when adding adding new multipliers by ladder. +* '/sellall multiplier list help' - can limit the list of multipliers by ladder and can control how many columns are in the display. @@ -386,7 +417,8 @@ The other method is a little more controlled, and that's using prison wand to se Prison has an advanced command handler that is able to do a lot of things. One of it's features is to provide more information on each command that it has registered. To activate this feature, just add the keyword `help` to the end of any command. Here are a few examples. ``` -/mines info help +/ranks autoconfigure help +/mines info help /ranks promote help /ranks command add help /prison support submit diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/LadderCommands.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/LadderCommands.java index 35df70b7f..f6ecf8139 100644 --- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/LadderCommands.java +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/LadderCommands.java @@ -370,12 +370,44 @@ public void ladderRemoveRank(CommandSender sender, @Command( identifier = "ranks ladder rankCostMultiplier", - description = "Sets or removes a ladder's Rank Cost Multiplier. Setting the " + - "value to zero will remove the multiplier from the calculations. The " + - "Rank Cost Multiplier from all ladders a player has active, will be " + - "summed together and applied to the cost of all of their ranks. The Rank " + - "Cost Multiplier represents a percentage, and can be either postive or " + - "negative. ", + description = "Sets a ladder's rank cost multiplier which is used to calculate " + + "a rank's cost on ladders that have them enabled. " + + "Setting the value to zero will remove that ladder's rank multiplier from " + + "the calculations. " + + "Rank Cost Multiplier represents a percentage, and can be either postive or " + + "negative, and is multiplied by the rank's position (1's based). " + + "This means that for ladders have have a rank cost multiplier, the " + + "multiplier increases by the rank's position, such that if the prestige " + + "ladder has a ranks cost multiplier of 0.1, the P1=0.1, P2=0.2, P3=0.3, etc... {br}" + + + "All rank cost multipliers for the player's rank on that ladder, are " + + "combined from all ladders the player is on, " + + "then this value is added to a value of 1.0 before being multiplied to the rank cost. " + + "This will result in a progressively more expensive rank cost for the " + + "player as they advance on multiple ladders. " + + "If a ladder has 'applyRankCostMultiplier' disabled, then rank costs on that " + + "ladder will not use the player's combined rank cost multiplier. {br}" + + + "This calculates " + + "what a player would have to pay when ranking up. " + + "It should be understood that a ladder can contribute to the total " + + "ranks multiplier, but yet it could ignore the ranks multiplier when " + + "calculating the rank costs for that ladder. {br}" + + + "Example of this kind of setup would be to have the " + + "default ladder apply the rank cost multiplier to its rank's costs, " + + "but yet have the default ladder set it's rank cost multiplier to a value of 0.0. " + + "Then have the prestige ladder ignore " + + "them, but have the prestige ladder contribute to the global rank " + + "cost multipliers. This configuration will result in rank costs increasing " + + "for the default ladder's ranks, as the player increases their prestige ranks. " + + "But yet the prestiges ladder rank costs will not be impacted " + + "by the rank cost multipliers. Using the example above for p1, p2, p3, etc, " + + "the rank costs on the default ladder will increase by 10 percent each time " + + "the player prestiges. At a 10% increase, the default rank costs will be " + + "twice as expensive when the are at P10, compared to when they were at " + + "p0 (no prestige rank)." + , onlyPlayers = false, permissions = "ranks.ladder" ) public void ladderSetRankCostMultiplier( CommandSender sender, @Arg( name = "ladderName" ) String ladderName, @@ -433,15 +465,15 @@ public void ladderSetRankCostMultiplier( CommandSender sender, @Command( identifier = "ranks ladder applyRankCostMultiplier", - description = "Controls if the rank costs multiplier should apply to the" + - "ranks on this ladder. If the ladder has a rank cost multipiler " + - "enabled, this setting will not effect its contribution to other " + - "the multiplier.", + description = "Controls if the rank costs multiplier should apply to the " + + "ranks on this ladder. This is an 'ON' or 'OFF' situation for the whole " + + "ladder, where the Rank Cost Multiplier will be ignored for a ladder " + + "if this is disabled.", onlyPlayers = false, permissions = "ranks.ladder" ) public void ladderApplyRankCostMultiplier( CommandSender sender, @Arg( name = "ladderName" ) String ladderName, @Arg( name = "applyRankCostMultiplier", def = "apply", - description = "Applies or disables the ranks on this ladder " + description = "Applies or disables the ranks on this ladder " + "from applying the rank multiplier to the rank cost for players." ) String applyRankCostMultiplier ) @@ -488,7 +520,9 @@ public void ladderApplyRankCostMultiplier( CommandSender sender, @Command( identifier = "ranks ladder resetRankCosts", - description = "For a given ladder, this command will reset all rank costs. " + description = "For a given ladder, this command will reset all rank costs " + + "based upon a formula, where each rank is progressivly more " + + "expensive. " + "This allow easier adjustments to many ranks at the same time. " + "The ranks within this ladder will not be changed, and they will be " + "processed in the same order in which they are listed with the " diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/RanksCommands.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/RanksCommands.java index f29f50f94..ffe8e804a 100644 --- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/RanksCommands.java +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/RanksCommands.java @@ -219,11 +219,14 @@ public boolean createRank(CommandSender sender, @Command(identifier = "ranks autoConfigure", description = "Auto configures Ranks, Mines, and Prestiges using " + "single letters A through Z for both the rank and mine names. Both ranks and mines are " + - "generated, they will also be linked together automatically. To set the starting price use " + - "'price=x'. To set multiplier 'mult=x'. AutoConfigure will try to merge any preexsiting ranks " + + "generated, they will also be linked together automatically. Prestige ranks will " + + "also be auto generated with a default of 25 that will be created. {br}" + + "To set the starting price use " + + "'price=x'. To set multiplier 'mult=x'. {br}" + + "AutoConfigure will try to merge any preexsiting ranks " + "and mines, but you must use the 'force' keyword in 'options' and force will " + "replace all blocks in preexisting " + - "mines. To keep preexisting blocks, use 'forceKeepBlocks' with the 'force' option. " + + "mines. To keep preexisting blocks, use 'forceKeepBlocks' with the 'force' option. {br}" + "The option 'full' will enable ranks, mines, and prestiges. No options will default to 'full'. " + "The options 'ranks', 'mines', and 'prestiges' will enable each of these if they are listed. " + @@ -234,10 +237,10 @@ public boolean createRank(CommandSender sender, "The option 'prestigeMult=x' is an additional multiplier for presetige ranks, with the " + "default value of 1. The cost for each prestige rank is based upon the initial " + "presetigeCost, times the prestige level so p3 will be 3 times the cost of p1 with the " + - "prestige multiplier will multipled against that value. So for default values " + - " with a 1.75 multipler p3 cost = 1_000_000_000 * 3 * 1.75. " + + "prestige multiplier will multiplied against that value. So for default values " + + " with a 1.75 multiplier p3 cost = 1_000_000_000 * 3 * 1.75. " + "Default values [full price=50000 mult=1.5 prestiges=25 presetigeCost=1000000000 " + - "prestigeMult=1] " + + "prestigeMult=1] {br}" + "Example of just adding more prestige ranks using the other default values: " + "'/ranks autoConfigure force prestiges presetiges=1000', no ranks and no mines will " + From e0b8c7e87f15fec97341d830bbf65e88841a100e Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Mon, 11 Sep 2023 00:02:20 -0400 Subject: [PATCH 101/151] Block Converters: Start to hook up block converters to auto features. Changed how block converters were structured to get them to work with the prison environment. Hooked up the Block Converter Event Trigger to the bukkit BlockBreakEvent. Explosions are not yet covered, will add support for them if this appears to work. --- docs/changelog_v3.3.x.md | 6 +- .../tech/mcprison/prison/PrisonCommand.java | 46 ++++- .../autofeatures/AutoFeaturesFileConfig.java | 15 ++ .../autofeatures/AutoFeaturesWrapper.java | 47 +++-- .../prison/autofeatures/BlockConverter.java | 11 ++ .../BlockConverterEventTrigger.java | 32 +++ .../BlockConverterOptionEventTrigger.java | 78 ++++++++ .../autofeatures/BlockConverterOptions.java | 27 +++ .../autofeatures/BlockConvertersData.java | 71 +++++++ .../BlockConvertersFileConfig.java | 185 +++++++++++++----- .../BlockConvertersInitializer.java | 48 +++++ .../prison/ranks/commands/RanksCommands.java | 2 + .../prison/spigot/SpigotPlatform.java | 5 + .../mcprison/prison/spigot/SpigotPrison.java | 9 + .../autofeatures/AutoManagerFeatures.java | 75 +++++++ .../events/AutoManagerBlockBreakEvents.java | 12 ++ 16 files changed, 596 insertions(+), 73 deletions(-) create mode 100644 prison-core/src/main/java/tech/mcprison/prison/autofeatures/BlockConverterEventTrigger.java create mode 100644 prison-core/src/main/java/tech/mcprison/prison/autofeatures/BlockConverterOptionEventTrigger.java create mode 100644 prison-core/src/main/java/tech/mcprison/prison/autofeatures/BlockConverterOptions.java create mode 100644 prison-core/src/main/java/tech/mcprison/prison/autofeatures/BlockConvertersData.java diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 93b22cc87..480a8fc76 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -14,7 +14,11 @@ These change logs represent the work that has been going on within prison. -# 3.3.0-alpha.15e 2023-09-09 +# 3.3.0-alpha.15e 2023-09-11 + +* **Block Converters: Start to hook up block converters to auto features.** +Changed how block converters were structured to get them to work with the prison environment. +Hooked up the Block Converter Event Trigger to the bukkit BlockBreakEvent. Explosions are not yet covered, will add support for them if this appears to work. * **Update docs and some command descriptions to make them a little more clearer as to what they do.** diff --git a/prison-core/src/main/java/tech/mcprison/prison/PrisonCommand.java b/prison-core/src/main/java/tech/mcprison/prison/PrisonCommand.java index 69891a374..7dd5c941e 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/PrisonCommand.java +++ b/prison-core/src/main/java/tech/mcprison/prison/PrisonCommand.java @@ -875,24 +875,54 @@ public void reloadAutoFeatures(CommandSender sender ) { sender.sendMessage( filePath ); } catch ( IOException e ) { - // Ingore + // Ignore } - try { +// try { +// +// if ( AutoFeaturesWrapper.getInstance().getBlockConvertersConfig() != null ) { +// +// File bcFile = AutoFeaturesWrapper.getInstance().getBlockConvertersConfig().getConfigFile(); +// if ( bcFile != null && bcFile.exists() ) { +// +// String filePath = bcFile.getCanonicalPath(); +// sender.sendMessage( filePath ); +// } +// } +// +// } +// catch ( IOException e ) { +// // Ignore +// } + } + + + @Command(identifier = "prison reload blockConverters", + description = "BlockConverters reload: Reloads the block converter settings. The current " + + "settings will be discarded before reloading the configuration file.", + onlyPlayers = false, permissions = "prison.autofeatures") + public void reloadBlockConverters(CommandSender sender ) { + + if ( AutoFeaturesWrapper.getBlockConvertersInstance() != null ) { - if ( AutoFeaturesWrapper.getInstance().getBlockConvertersConfig() != null ) { - - File bcFile = AutoFeaturesWrapper.getInstance().getBlockConvertersConfig().getConfigFile(); + AutoFeaturesWrapper.getBlockConvertersInstance().reloadConfig(); + + String message = "&7BlockConverters were reloaded. The new settings are now in effect. "; + sender.sendMessage( message ); + + try { + File bcFile = AutoFeaturesWrapper.getBlockConvertersInstance().getConfigFile(); if ( bcFile != null && bcFile.exists() ) { String filePath = bcFile.getCanonicalPath(); sender.sendMessage( filePath ); } } + catch ( IOException e ) { + // Ignore + } } - catch ( IOException e ) { - // Ingore - } + } diff --git a/prison-core/src/main/java/tech/mcprison/prison/autofeatures/AutoFeaturesFileConfig.java b/prison-core/src/main/java/tech/mcprison/prison/autofeatures/AutoFeaturesFileConfig.java index 1726b3344..b093c7a5a 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/autofeatures/AutoFeaturesFileConfig.java +++ b/prison-core/src/main/java/tech/mcprison/prison/autofeatures/AutoFeaturesFileConfig.java @@ -432,6 +432,21 @@ public enum AutoFeatures { blockCopperBlock(blockFeature, true), + + blockConverters(options), + isEnabledBlockConverters(blockConverters, false ), + + blockConverters_readme(blockConverters, + "Block converters are a new experimental component to prison that will " + + "provide much more control over all things related to blocks, including " + + "access through perms, ranks, or special functional behaviors. Eventually " + + "this will replace the list of hard coded blocks listed above for " + + "blocking and smelting."), + + isEnabledBlockConvertersEventTriggers(blockConverters, false ) + + + // examplesOnlyNotUsed, // exampleOfBlockConversions(examplesOnlyNotUsed), // diff --git a/prison-core/src/main/java/tech/mcprison/prison/autofeatures/AutoFeaturesWrapper.java b/prison-core/src/main/java/tech/mcprison/prison/autofeatures/AutoFeaturesWrapper.java index 4131b2abf..1439c45dd 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/autofeatures/AutoFeaturesWrapper.java +++ b/prison-core/src/main/java/tech/mcprison/prison/autofeatures/AutoFeaturesWrapper.java @@ -13,17 +13,17 @@ public class AutoFeaturesWrapper private AutoFeaturesFileConfig autoFeaturesConfig = null; - private BlockConvertersFileConfig blockConvertersConfig = null; + private static BlockConvertersFileConfig blockConvertersConfig = null; private AutoFeaturesWrapper() { super(); this.autoFeaturesConfig = new AutoFeaturesFileConfig(); - if ( Output.get().isDebug() ) { +// if ( Output.get().isDebug() ) { - this.blockConvertersConfig = new BlockConvertersFileConfig(); - } +// this.blockConvertersConfig = new BlockConvertersFileConfig(); +// } } public static AutoFeaturesWrapper getInstance() { @@ -40,26 +40,42 @@ public static AutoFeaturesWrapper getInstance() { } + public static BlockConvertersFileConfig getBlockConvertersInstance() { + if ( blockConvertersConfig == null ) { + + synchronized ( BlockConvertersFileConfig.class ) { + if ( blockConvertersConfig == null ) { + + blockConvertersConfig = new BlockConvertersFileConfig(); + +// blockConvertersConfig.reloadConfig(); + } + } + } + return blockConvertersConfig; + } + + public void reloadConfigs() { getAutoFeaturesConfig().reloadConfig(); - if ( Output.get().isDebug() && getBlockConvertersConfig() != null ) { - - getBlockConvertersConfig().reloadConfig(); - } +// if ( Output.get().isDebug() && getBlockConvertersConfig() != null ) { +// +// getBlockConvertersConfig().reloadConfig(); +// } } public AutoFeaturesFileConfig getAutoFeaturesConfig() { return autoFeaturesConfig; } - public BlockConvertersFileConfig getBlockConvertersConfig() { - return blockConvertersConfig; - } - - public void setBlockConvertersConfig(BlockConvertersFileConfig blockConvertersConfig) { - this.blockConvertersConfig = blockConvertersConfig; - } +// public BlockConvertersFileConfig getBlockConvertersConfig() { +// return blockConvertersConfig; +// } +// +// public void setBlockConvertersConfig(BlockConvertersFileConfig blockConvertersConfig) { +// this.blockConvertersConfig = blockConvertersConfig; +// } public boolean isBoolean( AutoFeatures feature ) { return autoFeaturesConfig.isFeatureBoolean( feature ); @@ -88,4 +104,5 @@ public List getListString( AutoFeatures feature ) { return results; } + } diff --git a/prison-core/src/main/java/tech/mcprison/prison/autofeatures/BlockConverter.java b/prison-core/src/main/java/tech/mcprison/prison/autofeatures/BlockConverter.java index 34b4678d7..7575a7225 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/autofeatures/BlockConverter.java +++ b/prison-core/src/main/java/tech/mcprison/prison/autofeatures/BlockConverter.java @@ -19,6 +19,8 @@ public class BlockConverter { private ArrayList permissions; private ArrayList outputs; + +// private ArrayList options; public BlockConverter( String blockName, int keyQuantity ) { super(); @@ -32,6 +34,8 @@ public BlockConverter( String blockName, int keyQuantity ) { this.permissions = new ArrayList<>(); this.outputs = new ArrayList<>(); + +// this.options = new ArrayList<>(); } public BlockConverter( String blockName, int keyQuantity, String mininumSpigotSemanticVersion ) { @@ -236,4 +240,11 @@ public void setOutputs(ArrayList outputs) { this.outputs = outputs; } +// public ArrayList getOptions() { +// return options; +// } +// public void setOptions(ArrayList options) { +// this.options = options; +// } + } diff --git a/prison-core/src/main/java/tech/mcprison/prison/autofeatures/BlockConverterEventTrigger.java b/prison-core/src/main/java/tech/mcprison/prison/autofeatures/BlockConverterEventTrigger.java new file mode 100644 index 000000000..0392d5cfc --- /dev/null +++ b/prison-core/src/main/java/tech/mcprison/prison/autofeatures/BlockConverterEventTrigger.java @@ -0,0 +1,32 @@ +package tech.mcprison.prison.autofeatures; + +import java.util.ArrayList; + +public class BlockConverterEventTrigger + extends BlockConverter { + + private ArrayList options; + + public BlockConverterEventTrigger( String blockName, int keyQuantity ) { + super( blockName, keyQuantity ); + + this.options = new ArrayList<>(); + } + + public BlockConverterEventTrigger( String blockName, int keyQuantity, String mininumSpigotSemanticVersion ) { + super( blockName, keyQuantity, mininumSpigotSemanticVersion ); + + this.options = new ArrayList<>(); + } + + public BlockConverterEventTrigger( String blockName ) { + this( blockName, 1 ); + } + + public ArrayList getOptions() { + return options; + } + public void setOptions(ArrayList options) { + this.options = options; + } +} diff --git a/prison-core/src/main/java/tech/mcprison/prison/autofeatures/BlockConverterOptionEventTrigger.java b/prison-core/src/main/java/tech/mcprison/prison/autofeatures/BlockConverterOptionEventTrigger.java new file mode 100644 index 000000000..ab5f36c9c --- /dev/null +++ b/prison-core/src/main/java/tech/mcprison/prison/autofeatures/BlockConverterOptionEventTrigger.java @@ -0,0 +1,78 @@ +package tech.mcprison.prison.autofeatures; + +/** + *

The event trigger uses the block type that this is associated with to + * identify when it should apply. + *

+ * + */ +public class BlockConverterOptionEventTrigger +// extends BlockConverterOptions + { + +// private String blockTriggerName; + + private String eventPluginName; + + private String description; + + private String eventPluginPriority; + + private String eventPluginClassName; + + private boolean allowPrisonToProccessDrops; + + /** + * This is to be used as a transient cache of working with + * the external event. + */ + private transient Object externalResource; + + public BlockConverterOptionEventTrigger() { + super(); +// super( BlockConverterOptionType.event_trigger ); + } + + public String getEventPluginName() { + return eventPluginName; + } + public void setEventPluginName(String eventPluginName) { + this.eventPluginName = eventPluginName; + } + + public String getDescription() { + return description; + } + public void setDescription(String description) { + this.description = description; + } + + public String getEventPluginPriority() { + return eventPluginPriority; + } + public void setEventPluginPriority(String eventPluginPriority) { + this.eventPluginPriority = eventPluginPriority; + } + + public String getEventPluginClassName() { + return eventPluginClassName; + } + public void setEventPluginClassName(String eventPluginClassName) { + this.eventPluginClassName = eventPluginClassName; + } + + public boolean isAllowPrisonToProccessDrops() { + return allowPrisonToProccessDrops; + } + public void setAllowPrisonToProccessDrops(boolean allowPrisonToProccessDrops) { + this.allowPrisonToProccessDrops = allowPrisonToProccessDrops; + } + + public Object getExternalResource() { + return externalResource; + } + public void setExternalResource(Object externalResource) { + this.externalResource = externalResource; + } + +} diff --git a/prison-core/src/main/java/tech/mcprison/prison/autofeatures/BlockConverterOptions.java b/prison-core/src/main/java/tech/mcprison/prison/autofeatures/BlockConverterOptions.java new file mode 100644 index 000000000..ad17544ce --- /dev/null +++ b/prison-core/src/main/java/tech/mcprison/prison/autofeatures/BlockConverterOptions.java @@ -0,0 +1,27 @@ +package tech.mcprison.prison.autofeatures; + +public abstract class BlockConverterOptions { + + private final BlockConverterOptionType blockConverterOptionType; + + public BlockConverterOptions() { + super(); + + this.blockConverterOptionType = BlockConverterOptionType.no_options_set; + } + public BlockConverterOptions( BlockConverterOptionType optionType ) { + super(); + + this.blockConverterOptionType = optionType; + } + + public enum BlockConverterOptionType { + no_options_set, + event_trigger; + } + + public BlockConverterOptionType getBlockConverterOptionType() { + return blockConverterOptionType; + } + +} diff --git a/prison-core/src/main/java/tech/mcprison/prison/autofeatures/BlockConvertersData.java b/prison-core/src/main/java/tech/mcprison/prison/autofeatures/BlockConvertersData.java new file mode 100644 index 000000000..3d01485c9 --- /dev/null +++ b/prison-core/src/main/java/tech/mcprison/prison/autofeatures/BlockConvertersData.java @@ -0,0 +1,71 @@ +package tech.mcprison.prison.autofeatures; + +import java.util.TreeMap; + +import tech.mcprison.prison.autofeatures.BlockConvertersFileConfig.BlockConverterTypes; +import tech.mcprison.prison.file.FileIOData; + +public class BlockConvertersData + implements FileIOData +{ + + private TreeMap> blockConverters; + private TreeMap blockConvertersEventTiggers; + + private TreeMap processAutoFeaturesAllBlocks = null; + + public BlockConvertersData() { + super(); + + this.blockConverters = new TreeMap<>(); + this.blockConvertersEventTiggers = new TreeMap<>(); + + this.processAutoFeaturesAllBlocks = new TreeMap<>(); + } + + + + /** + *

Force the BlockConverterEventTriggers to BlockConverter so it can be + * processed by the core selectors that deal with BlockConverter objects + * and the player's. + *

+ * + * @param blockName + * @return + */ + public TreeMap getBlockConvertersEventTiggers(String blockName) { + TreeMap results = new TreeMap<>(); + + if ( getBlockConvertersEventTiggers().containsKey( blockName ) ) { + results.put( blockName, + (BlockConverter) getBlockConvertersEventTiggers().get( blockName ) + ); + } + + return results; + } + + + public TreeMap> getBlockConverters() { + return blockConverters; + } + public void setBlockConverters(TreeMap> blockConverters) { + this.blockConverters = blockConverters; + } + + public TreeMap getBlockConvertersEventTiggers() { + return blockConvertersEventTiggers; + } + public void setBlockConvertersEventTiggers(TreeMap blockConvertersEventTiggers) { + this.blockConvertersEventTiggers = blockConvertersEventTiggers; + } + + public TreeMap getProcessAutoFeaturesAllBlocks() { + return processAutoFeaturesAllBlocks; + } + public void setProcessAutoFeaturesAllBlocks(TreeMap processAutoFeaturesAllBlocks) { + this.processAutoFeaturesAllBlocks = processAutoFeaturesAllBlocks; + } + +} diff --git a/prison-core/src/main/java/tech/mcprison/prison/autofeatures/BlockConvertersFileConfig.java b/prison-core/src/main/java/tech/mcprison/prison/autofeatures/BlockConvertersFileConfig.java index 5bd4210a0..5f3f2ef5b 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/autofeatures/BlockConvertersFileConfig.java +++ b/prison-core/src/main/java/tech/mcprison/prison/autofeatures/BlockConvertersFileConfig.java @@ -6,38 +6,48 @@ import java.util.TreeMap; import tech.mcprison.prison.Prison; -import tech.mcprison.prison.file.FileIOData; +import tech.mcprison.prison.autofeatures.AutoFeaturesFileConfig.AutoFeatures; import tech.mcprison.prison.file.JsonFileIO; import tech.mcprison.prison.internal.ItemStack; import tech.mcprison.prison.internal.block.PrisonBlock; +import tech.mcprison.prison.output.Output; import tech.mcprison.prison.ranks.data.RankPlayer; -public class BlockConvertersFileConfig - implements FileIOData { +public class BlockConvertersFileConfig { public static final String FILE_NAME__BLOCK_CONVERTS_CONFIG_JSON = "/blockConvertersConfig.json"; private transient File configFile; - private TreeMap> blockConverters; + private transient BlockConvertersData bcData; - private TreeMap processAutoFeaturesAllBlocks = null; +// private TreeMap> blockConverters; +// private TreeMap blockConvertersEventTiggers; + + +// private TreeMap processAutoFeaturesAllBlocks = null; public enum BlockConverterTypes { aSample01, autoPickupFeatures, blockFeatures, - smeltFeatures + smeltFeatures, + eventTriggers ; } public BlockConvertersFileConfig() { super(); - this.blockConverters = new TreeMap<>(); + this.bcData = new BlockConvertersData(); + +// this.blockConverters = new TreeMap<>(); +// this.blockConvertersEventTiggers = new TreeMap<>(); +// +// this.processAutoFeaturesAllBlocks = new TreeMap<>(); - this.processAutoFeaturesAllBlocks = new TreeMap<>(); + reloadConfig(); } @@ -119,6 +129,7 @@ public BlockConverter getBlockConverter( RankPlayer player, String blockName, if ( player != null && blockName != null && bcType != null ) { BlockConverter temp = getBlockConverter( blockName, bcType ); + if ( temp != null && temp.getPermissions().size() == 0 ) { results = temp; } @@ -150,7 +161,15 @@ public BlockConverter getBlockConverter( String blockName, BlockConverterTypes b if ( blockName != null && bcType != null ) { - TreeMap bConverters = getBlockConverters().get(bcType); + TreeMap bConverters = null; + + if ( bcType == BlockConverterTypes.eventTriggers ) { + bConverters = getBcData().getBlockConvertersEventTiggers( blockName ); + } + else { + + bConverters = getBcData().getBlockConverters().get(bcType); + } if ( bConverters.containsKey( blockName.toLowerCase() ) ) { results = bConverters.get( blockName.toLowerCase() ); @@ -214,17 +233,57 @@ private List getBlockConverterOutputs(RankPlayer player, B return outputs; } + /** + *

This function will take a player, and check if that player should have the ability to process all + * blocks under auto features. This is the "global" setting that bypasses checking individual block types. + *

+ * + *

If the auto features settings `options.autoFeatures.isAutoFeaturesEnabled: false` is + * disabled (set to false), then this will apply to the normal drops if + * `options.normalDrop.handleNormalDropsEvents: true' is enabled (set to true). + * If both of those are set to disabled, then no blocks will be processed. + *

+ * + * @param player + * @return + */ + public Boolean isProcessAutoFeaturesAllBlocks( RankPlayer player ) { + + if ( !getBcData().getProcessAutoFeaturesAllBlocks().containsKey( player.getName() ) ) { + BlockConverterResults allBlocksBCR = getBlockConverterItemStacks( player, "*all*", 1, BlockConverterTypes.autoPickupFeatures ); + + BlockConverter allBlocks = allBlocksBCR.getBlockConverter(); + + boolean playerAllBlocks = ( allBlocks != null && allBlocks.isEnabled() ); + + getBcData().getProcessAutoFeaturesAllBlocks().put( player.getName(), playerAllBlocks ); + } + + return getBcData().getProcessAutoFeaturesAllBlocks().get( player.getName() ); + } - + /** + *

This loads the sample block converters. If a new section is added, it will + * add the new section, along with the examples, to the existing block + * converters and then save everything. + *

+ * + *

This should only be called from the reloadConfig() function. + *

+ * + * @return + */ private boolean initialConfig() { boolean dirty = false; BlockConvertersInitializer initializer = new BlockConvertersInitializer(); - dirty = initializer.checkConfigs( getBlockConverters() ); + boolean d1 = initializer.checkConfigs( getBcData().getBlockConverters() ); + boolean d2 = initializer.checkConfigsEventTrigger( getBcData().getBlockConvertersEventTiggers() ); + dirty = d1 || d2; - if ( initializer.validateBlockConverters( getBlockConverters() ) ) { + if ( initializer.validateBlockConverters( getBcData().getBlockConverters() ) ) { dirty = true; } @@ -241,63 +300,91 @@ public File getConfigFile() { return configFile; } + /** + *

This actually is how the BlockConverters are loaded and created. + * There should be no other way to load the configs. + * + * This class can be instantiated, but only if block converters are + * enabled within the AutoFeatures config file will they be loaded. + *

+ * + */ public void reloadConfig() { - JsonFileIO jfio = new JsonFileIO(); - - BlockConvertersFileConfig temp = (BlockConvertersFileConfig) jfio.readJsonFile( getConfigFile(), this ); - if ( temp != null ) { - setBlockConverters( temp.getBlockConverters() ); - } - - boolean dirty = initialConfig(); - - if ( dirty ) { - saveToJson(); + Output.get().logInfo( "###### blockConverters: reloadConfig(): 1"); + if ( AutoFeaturesWrapper.getInstance().isBoolean( AutoFeatures.isEnabledBlockConverters ) ) { + Output.get().logInfo( "###### blockConverters: reloadConfig)(: 2"); + JsonFileIO jfio = new JsonFileIO(); + + BlockConvertersData temp = (BlockConvertersData) jfio.readJsonFile( getConfigFile(), getBcData() ); + + if ( temp != null ) { + setBcData( temp ); +// setBlockConverters( temp.getBlockConverters() ); + } + + boolean dirty = initialConfig(); + + if ( dirty ) { + saveToJson(); + } } + } public void saveToJson() { JsonFileIO jfio = new JsonFileIO(); - jfio.saveJsonFile(getConfigFile(), this ); + jfio.saveJsonFile(getConfigFile(), getBcData() ); + + Output.get().logDebug( + "BlockConverters: saved config file: %s", + getConfigFile().getAbsolutePath() ); } - public TreeMap> getBlockConverters() { - return blockConverters; +// public TreeMap> getBlockConverters() { +// return blockConverters; +// } +// public void setBlockConverters(TreeMap> blockConverters) { +// this.blockConverters = blockConverters; +// } +// +// public TreeMap getBlockConvertersEventTiggers() { +// return blockConvertersEventTiggers; +// } +// public void setBlockConvertersEventTiggers(TreeMap blockConvertersEventTiggers) { +// this.blockConvertersEventTiggers = blockConvertersEventTiggers; +// } + + + + public BlockConvertersData getBcData() { + return bcData; } - public void setBlockConverters(TreeMap> blockConverters) { - this.blockConverters = blockConverters; + public void setBcData(BlockConvertersData bcData) { + this.bcData = bcData; } /** - *

This function will take a player, and check if that player should have the ability to process all - * blocks under auto features. This is the "global" setting that bypasses checking individual block types. + *

This gets the BlockConverterEventTrigger for the block name provided, based upon player permissions + * if they apply. *

* - *

If the auto features settings `options.autoFeatures.isAutoFeaturesEnabled: false` is - * disabled (set to false), then this will apply to the normal drops if - * `options.normalDrop.handleNormalDropsEvents: true' is enabled (set to true). - * If both of those are set to disabled, then no blocks will be processed. - *

- * - * @param player + * @param rPlayer + * @param blockName * @return */ - public Boolean isProcessAutoFeaturesAllBlocks( RankPlayer player ) { + public List findEventTrigger(RankPlayer rPlayer, String blockName) { + List eventTriggers = null; - if ( !processAutoFeaturesAllBlocks.containsKey( player.getName() ) ) { - BlockConverterResults allBlocksBCR = getBlockConverterItemStacks( player, "*all*", 1, BlockConverterTypes.autoPickupFeatures ); - - BlockConverter allBlocks = allBlocksBCR.getBlockConverter(); - - boolean playerAllBlocks = ( allBlocks != null && allBlocks.isEnabled() ); - - processAutoFeaturesAllBlocks.put( player.getName(), playerAllBlocks ); + BlockConverterEventTrigger bcet = (BlockConverterEventTrigger) + getBlockConverter( rPlayer, blockName, BlockConverterTypes.eventTriggers ); + + if ( bcet != null && bcet.getOptions().size() > 0 ) { + eventTriggers = bcet.getOptions(); } - return processAutoFeaturesAllBlocks.get( player.getName() ); + return eventTriggers; } - - + } diff --git a/prison-core/src/main/java/tech/mcprison/prison/autofeatures/BlockConvertersInitializer.java b/prison-core/src/main/java/tech/mcprison/prison/autofeatures/BlockConvertersInitializer.java index 148aed76d..b1ffd265b 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/autofeatures/BlockConvertersInitializer.java +++ b/prison-core/src/main/java/tech/mcprison/prison/autofeatures/BlockConvertersInitializer.java @@ -36,6 +36,20 @@ public boolean checkConfigs(TreeMap treeMap) { + boolean isDirty = false; + + if ( treeMap != null && treeMap.size() == 0 ) { + + loadDefaultBlockConvertersEventTriggers(treeMap); + + isDirty = true; + + } + + return isDirty; + } + private void loadDefaultBlockConverters( BlockConverterTypes bcType, TreeMap blockConverters ) { @@ -63,11 +77,23 @@ private void loadDefaultBlockConverters( BlockConverterTypes bcType, TreeMap blockConverters ) { + + loadDefaultEventTriggers( blockConverters ); + + } + private void loadDefaultBlockConverterSample01(TreeMap blockConverters) { @@ -92,7 +118,29 @@ private void loadDefaultBlockConverterSample01(TreeMap b blockConverters.put( bc2.getKeyBlockName(), bc2 ); } + + + private void loadDefaultEventTriggers(TreeMap blockConverters ) { + + BlockConverterEventTrigger bc1 = new BlockConverterEventTrigger( "*not_a_real_block*" ); + + bc1.getPermissions().add("prison.not.used.sample.admin"); + + BlockConverterOptionEventTrigger et1 = new BlockConverterOptionEventTrigger(); + et1.setEventPluginName( "DropEdit2" ); + et1.setDescription( "Sample of how an EventTrigger is setup. Use " + + "'/prison support listeners blockEvent' to get details."); + et1.setEventPluginPriority( "HIGHEST" ); + et1.setEventPluginClassName( "DropEdit.ListenersLegacy" ); + + bc1.getOptions().add( et1 ); + + blockConverters.put( bc1.getKeyBlockName(), bc1 ); + + } + + public void loadDefaultBlockConverterSmelters( TreeMap blockConverters ) { diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/RanksCommands.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/RanksCommands.java index ffe8e804a..c9bfc6a3e 100644 --- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/RanksCommands.java +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/RanksCommands.java @@ -637,6 +637,8 @@ public void autoConfigureRanks(CommandSender sender, // Reloads autoFeatures and blockConverters: AutoFeaturesWrapper.getInstance().reloadConfigs(); + AutoFeaturesWrapper.getBlockConvertersInstance().reloadConfig(); + // Reset all player to the first rank on the default ladder: PrisonRanks.getInstance().checkAllPlayersForJoin(); diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/SpigotPlatform.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/SpigotPlatform.java index e2fac05db..3e32a1bae 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/SpigotPlatform.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/SpigotPlatform.java @@ -2172,6 +2172,11 @@ public List getActiveFeatures( boolean showLaddersAndRanks ) { AutoFeaturesWrapper afw = AutoFeaturesWrapper.getInstance(); // afw.reloadConfigs(); +// AutoFeaturesWrapper.getBlockConvertersInstance(); + + + + boolean isAutoManagerEnabled = afw.isBoolean( AutoFeatures.isAutoManagerEnabled ); results.add( String.format("AutoManager Enabled:&b %s", isAutoManagerEnabled) ); diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/SpigotPrison.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/SpigotPrison.java index ebc08888c..bcb8c58f0 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/SpigotPrison.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/SpigotPrison.java @@ -40,6 +40,7 @@ import tech.mcprison.prison.PrisonCommand; import tech.mcprison.prison.PrisonCommand.RegisteredPluginsData; import tech.mcprison.prison.alerts.Alerts; +import tech.mcprison.prison.autofeatures.AutoFeaturesWrapper; import tech.mcprison.prison.backups.PrisonBackups; import tech.mcprison.prison.integration.Integration; import tech.mcprison.prison.integration.IntegrationType; @@ -335,6 +336,14 @@ public void onEnableStartup() { // Sellall set to disabled since it will be set to the correct value in enableModulesAndCommands(): isSellAllEnabled = false; + + + // Load the autoFeaturesConfig.yml and blockConvertersConfig.json files: + AutoFeaturesWrapper.getInstance(); + AutoFeaturesWrapper.getBlockConvertersInstance(); + + + // This is the loader for modules and commands: enableModulesAndCommands(); diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerFeatures.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerFeatures.java index 1b5ae337f..ea70b0b54 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerFeatures.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerFeatures.java @@ -17,16 +17,20 @@ import org.bukkit.entity.ArmorStand; import org.bukkit.entity.EntityType; import org.bukkit.entity.Player; +import org.bukkit.event.EventException; import org.bukkit.event.HandlerList; import org.bukkit.event.block.BlockBreakEvent; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.plugin.RegisteredListener; import com.cryptomorin.xseries.XMaterial; import com.vk2gpz.tokenenchant.api.TokenEnchantAPI; import tech.mcprison.prison.Prison; import tech.mcprison.prison.autofeatures.AutoFeaturesFileConfig.AutoFeatures; +import tech.mcprison.prison.autofeatures.AutoFeaturesWrapper; +import tech.mcprison.prison.autofeatures.BlockConverterOptionEventTrigger; import tech.mcprison.prison.cache.PlayerCache; import tech.mcprison.prison.internal.block.PrisonBlock; import tech.mcprison.prison.internal.block.PrisonBlock.PrisonBlockType; @@ -34,6 +38,8 @@ import tech.mcprison.prison.output.ChatDisplay; import tech.mcprison.prison.output.Output; import tech.mcprison.prison.output.Output.DebugTarget; +import tech.mcprison.prison.ranks.PrisonRanks; +import tech.mcprison.prison.ranks.data.RankPlayer; import tech.mcprison.prison.spigot.SpigotPrison; import tech.mcprison.prison.spigot.SpigotUtil; import tech.mcprison.prison.spigot.api.PrisonMinesBlockBreakEvent; @@ -3248,6 +3254,75 @@ private List calculateDropAdditionsGravelFlint(SpigotItemStack return adds; } + public boolean checkBlockConverterEventTrigger(PrisonMinesBlockBreakEvent pmEvent, BlockBreakEvent event ) { + boolean terminate = false; + + RankPlayer rPlayer = PrisonRanks.getInstance().getPlayerManager().getPlayer( pmEvent.getSpigotPlayer() ); + String blockName = pmEvent.getSpigotBlock().getBlockName(); + + List eventTriggers = + AutoFeaturesWrapper.getBlockConvertersInstance().findEventTrigger( rPlayer, blockName ); + + if ( eventTriggers != null ) { + for (BlockConverterOptionEventTrigger eventTrigger : eventTriggers) { + RegisteredListener listener = null; + + if ( eventTrigger.getExternalResource() == null ) { + // Try to hook in to the external resource (the plugin listener): + // Adding this listener to the eventTrigger will be like a cache: + + listener = findBlockBreakEventListener( + eventTrigger.getEventPluginName(), + eventTrigger.getEventPluginPriority(), + eventTrigger.getEventPluginClassName() ); + + if ( listener != null ) { + eventTrigger.setExternalResource( listener ); + } + } + + if ( listener == null && eventTrigger.getExternalResource() != null ) { + + listener = (RegisteredListener) eventTrigger.getExternalResource(); + } + + if ( listener != null ) { + + try { + // This is where the magic happens... triggers the event listener: + listener.callEvent( event ); + + if ( !eventTrigger.isAllowPrisonToProccessDrops() ) { + terminate = true; + } + } + catch (EventException e) { + } + } + + } + } + + return terminate; + } + + private RegisteredListener findBlockBreakEventListener( String plugin, String priority, String className ) { + RegisteredListener results = null; + + for ( RegisteredListener listener : BlockBreakEvent.getHandlerList().getRegisteredListeners() ) { + + if ( plugin.equalsIgnoreCase( listener.getPlugin().getName() ) && + priority.equalsIgnoreCase( listener.getPriority().name() ) && + listener.getClass().getName().endsWith( className ) ) { + + results = listener; + break; + } + + } + return results; + } + public Random getRandom() { return random; } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerBlockBreakEvents.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerBlockBreakEvents.java index dec8fbdb8..367871511 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerBlockBreakEvents.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerBlockBreakEvents.java @@ -296,6 +296,8 @@ private void handleBlockBreakEvent( BlockBreakEvent e, BlockBreakPriority bbPrio debugInfo.append( eventResults.getDebugInfo() ); + + // Process all priorities if the event has not been canceled, and // process the MONITOR priority even if the event was canceled: if ( !bbPriority.isMonitor() && !e.isCancelled() || @@ -333,6 +335,15 @@ private void handleBlockBreakEvent( BlockBreakEvent e, BlockBreakPriority bbPrio return; } + + // Check for BlockConverters Event Triggers: + if ( checkBlockConverterEventTrigger( pmEvent, e ) ) { + + e.setCancelled( true ); + return; + } + + // Validate the event. if ( !validateEvent( pmEvent ) ) { @@ -514,6 +525,7 @@ public void run() { printDebugInfo( pmEvent, start ); } + protected int checkBonusXp( Player player, Block block, ItemStack item ) { int bonusXp = 0; From 4c26b986c9e6db8a2210add9847ed3e5d7897f79 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 16 Sep 2023 11:56:14 -0400 Subject: [PATCH 102/151] Block Converters - Event Triggers - Had issues with block names not matching, so using all lower case. When using an event trigger it now logs the debug info to the console. This will need more work, such as block removal and logging as if it were a MONITOR priority. At this point, we are testing to confirm that the event is actually being triggered. So far it looks like it is working as intended. --- docs/changelog_v3.3.x.md | 8 ++++++- .../autofeatures/BlockConvertersData.java | 8 ++++--- .../BlockConvertersFileConfig.java | 8 ++++--- .../autofeatures/AutoManagerFeatures.java | 24 ++++++++++++++++++- .../events/AutoManagerBlockBreakEvents.java | 2 ++ 5 files changed, 42 insertions(+), 8 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 480a8fc76..618c5fc2f 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -14,7 +14,13 @@ These change logs represent the work that has been going on within prison. -# 3.3.0-alpha.15e 2023-09-11 +# 3.3.0-alpha.15e 2023-09-16 + + +* **Block Converters - Event Triggers - Had issues with block names not matching, so using all lower case. When using an event trigger it now logs the debug info to the console.** +This will need more work, such as block removal and logging as if it were a MONITOR priority. +At this point, we are testing to confirm that the event is actually being triggered. So far it looks like it is working as intended. + * **Block Converters: Start to hook up block converters to auto features.** Changed how block converters were structured to get them to work with the prison environment. diff --git a/prison-core/src/main/java/tech/mcprison/prison/autofeatures/BlockConvertersData.java b/prison-core/src/main/java/tech/mcprison/prison/autofeatures/BlockConvertersData.java index 3d01485c9..32939ac97 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/autofeatures/BlockConvertersData.java +++ b/prison-core/src/main/java/tech/mcprison/prison/autofeatures/BlockConvertersData.java @@ -37,9 +37,11 @@ public BlockConvertersData() { public TreeMap getBlockConvertersEventTiggers(String blockName) { TreeMap results = new TreeMap<>(); - if ( getBlockConvertersEventTiggers().containsKey( blockName ) ) { - results.put( blockName, - (BlockConverter) getBlockConvertersEventTiggers().get( blockName ) + String key = blockName.toLowerCase(); + + if ( getBlockConvertersEventTiggers().containsKey( key ) ) { + results.put( key, + (BlockConverter) getBlockConvertersEventTiggers().get( key ) ); } diff --git a/prison-core/src/main/java/tech/mcprison/prison/autofeatures/BlockConvertersFileConfig.java b/prison-core/src/main/java/tech/mcprison/prison/autofeatures/BlockConvertersFileConfig.java index 5f3f2ef5b..09272aba9 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/autofeatures/BlockConvertersFileConfig.java +++ b/prison-core/src/main/java/tech/mcprison/prison/autofeatures/BlockConvertersFileConfig.java @@ -163,16 +163,18 @@ public BlockConverter getBlockConverter( String blockName, BlockConverterTypes b TreeMap bConverters = null; + String key = blockName.toLowerCase(); + if ( bcType == BlockConverterTypes.eventTriggers ) { - bConverters = getBcData().getBlockConvertersEventTiggers( blockName ); + bConverters = getBcData().getBlockConvertersEventTiggers( key ); } else { bConverters = getBcData().getBlockConverters().get(bcType); } - if ( bConverters.containsKey( blockName.toLowerCase() ) ) { - results = bConverters.get( blockName.toLowerCase() ); + if ( bConverters.containsKey( key ) ) { + results = bConverters.get( key ); } } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerFeatures.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerFeatures.java index ea70b0b54..d1e5ef6f3 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerFeatures.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerFeatures.java @@ -3257,6 +3257,8 @@ private List calculateDropAdditionsGravelFlint(SpigotItemStack public boolean checkBlockConverterEventTrigger(PrisonMinesBlockBreakEvent pmEvent, BlockBreakEvent event ) { boolean terminate = false; + long start = System.currentTimeMillis(); + RankPlayer rPlayer = PrisonRanks.getInstance().getPlayerManager().getPlayer( pmEvent.getSpigotPlayer() ); String blockName = pmEvent.getSpigotBlock().getBlockName(); @@ -3264,6 +3266,8 @@ public boolean checkBlockConverterEventTrigger(PrisonMinesBlockBreakEvent pmEven AutoFeaturesWrapper.getBlockConvertersInstance().findEventTrigger( rPlayer, blockName ); if ( eventTriggers != null ) { + StringBuilder sb = new StringBuilder(); + for (BlockConverterOptionEventTrigger eventTrigger : eventTriggers) { RegisteredListener listener = null; @@ -3289,6 +3293,12 @@ public boolean checkBlockConverterEventTrigger(PrisonMinesBlockBreakEvent pmEven if ( listener != null ) { try { + + if ( sb.length() > 0 ) { + sb.append( " " ); + } + sb.append( eventTrigger.getEventPluginName() ); + // This is where the magic happens... triggers the event listener: listener.callEvent( event ); @@ -3301,6 +3311,17 @@ public boolean checkBlockConverterEventTrigger(PrisonMinesBlockBreakEvent pmEven } } + + long stop = System.currentTimeMillis(); + double durationMs = (stop - start) / 1_000_000.0d; + + DecimalFormat dFmt = new DecimalFormat( "#,##0.000" ); + + String msg = String.format( + "(BlockConverter eventTrigger: %s : %s ms) ", + sb, + dFmt.format( durationMs ) ); + pmEvent.getDebugInfo().append( msg ); } return terminate; @@ -3313,7 +3334,8 @@ private RegisteredListener findBlockBreakEventListener( String plugin, String pr if ( plugin.equalsIgnoreCase( listener.getPlugin().getName() ) && priority.equalsIgnoreCase( listener.getPriority().name() ) && - listener.getClass().getName().endsWith( className ) ) { + listener.getListener().getClass().getName().endsWith( className ) + ) { results = listener; break; diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerBlockBreakEvents.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerBlockBreakEvents.java index 367871511..282b1004b 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerBlockBreakEvents.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerBlockBreakEvents.java @@ -340,6 +340,8 @@ private void handleBlockBreakEvent( BlockBreakEvent e, BlockBreakPriority bbPrio if ( checkBlockConverterEventTrigger( pmEvent, e ) ) { e.setCancelled( true ); + + printDebugInfo( pmEvent, start ); return; } From 45b8aa60a047fe44d42f0b1679af4f5502052ca6 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 16 Sep 2023 12:00:54 -0400 Subject: [PATCH 103/151] Mines block edit - Found a problem where if you are trying to edit a block and the name does not match, it was causing an error. Now reports that the block name is invalid. --- docs/changelog_v3.3.x.md | 3 +++ .../mcprison/prison/mines/commands/MinesBlockCommands.java | 7 ++++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 618c5fc2f..f13bbd989 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -17,6 +17,9 @@ These change logs represent the work that has been going on within prison. # 3.3.0-alpha.15e 2023-09-16 +* **Mines block edit - Found a problem where if you are trying to edit a block and the name does not match, it was causing an error.** Now reports that the block name is invalid. + + * **Block Converters - Event Triggers - Had issues with block names not matching, so using all lower case. When using an event trigger it now logs the debug info to the console.** This will need more work, such as block removal and logging as if it were a MONITOR priority. At this point, we are testing to confirm that the event is actually being triggered. So far it looks like it is working as intended. diff --git a/prison-mines/src/main/java/tech/mcprison/prison/mines/commands/MinesBlockCommands.java b/prison-mines/src/main/java/tech/mcprison/prison/mines/commands/MinesBlockCommands.java index f4ae83f64..61b967958 100644 --- a/prison-mines/src/main/java/tech/mcprison/prison/mines/commands/MinesBlockCommands.java +++ b/prison-mines/src/main/java/tech/mcprison/prison/mines/commands/MinesBlockCommands.java @@ -340,7 +340,12 @@ public void setBlockCommand(CommandSender sender, prisonBlock = prisonBlockTypes.getBlockTypesByName( block ); } - + if ( block == null || prisonBlock == null ) { + + sender.sendMessage( + String.format( "Invalid blockk name: [%s]", block ) ); + return; + } // Change behavior: If trying to change a block that is not in the mine, then instead add it: if (!m.isInMine(prisonBlock)) { From 3a1e447f051cc0c0f94b0be536d5ffc5ef8a50e4 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sun, 17 Sep 2023 10:33:30 -0400 Subject: [PATCH 104/151] BlockConverters EventTriggers: Setup more controls within the settings of a blockEvent. Setup the ability to control processing of drops: if disabled, it will treat the block event as a MONITOR. This allows the block to be counted correctly. Setup the ability to ignore the block type within all explosions, so each block would have to be broken individually. Setup the ability to remove the block without dropping anything since another plugin would have already processed the block, so nothing would remain to be done with it. --- .../BlockConverterOptionEventTrigger.java | 18 ++++++ .../BlockConvertersFileConfig.java | 58 ++++++++++++++++++- .../BlockConvertersInitializer.java | 4 ++ 3 files changed, 78 insertions(+), 2 deletions(-) diff --git a/prison-core/src/main/java/tech/mcprison/prison/autofeatures/BlockConverterOptionEventTrigger.java b/prison-core/src/main/java/tech/mcprison/prison/autofeatures/BlockConverterOptionEventTrigger.java index ab5f36c9c..bf20a5ad8 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/autofeatures/BlockConverterOptionEventTrigger.java +++ b/prison-core/src/main/java/tech/mcprison/prison/autofeatures/BlockConverterOptionEventTrigger.java @@ -22,6 +22,10 @@ public class BlockConverterOptionEventTrigger private boolean allowPrisonToProccessDrops; + private boolean removeBlockWithoutDrops; + + private boolean ignoreBlockInExplosionEvents; + /** * This is to be used as a transient cache of working with * the external event. @@ -68,6 +72,20 @@ public void setAllowPrisonToProccessDrops(boolean allowPrisonToProccessDrops) { this.allowPrisonToProccessDrops = allowPrisonToProccessDrops; } + public boolean isRemoveBlockWithoutDrops() { + return removeBlockWithoutDrops; + } + public void setRemoveBlockWithoutDrops(boolean removeBlockWithoutDrops) { + this.removeBlockWithoutDrops = removeBlockWithoutDrops; + } + + public boolean isIgnoreBlockInExplosionEvents() { + return ignoreBlockInExplosionEvents; + } + public void setIgnoreBlockInExplosionEvents(boolean ignoreBlockInExplosionEvents) { + this.ignoreBlockInExplosionEvents = ignoreBlockInExplosionEvents; + } + public Object getExternalResource() { return externalResource; } diff --git a/prison-core/src/main/java/tech/mcprison/prison/autofeatures/BlockConvertersFileConfig.java b/prison-core/src/main/java/tech/mcprison/prison/autofeatures/BlockConvertersFileConfig.java index 09272aba9..5bb8ddbd3 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/autofeatures/BlockConvertersFileConfig.java +++ b/prison-core/src/main/java/tech/mcprison/prison/autofeatures/BlockConvertersFileConfig.java @@ -3,6 +3,7 @@ import java.io.File; import java.util.ArrayList; import java.util.List; +import java.util.Set; import java.util.TreeMap; import tech.mcprison.prison.Prison; @@ -313,9 +314,7 @@ public File getConfigFile() { */ public void reloadConfig() { - Output.get().logInfo( "###### blockConverters: reloadConfig(): 1"); if ( AutoFeaturesWrapper.getInstance().isBoolean( AutoFeatures.isEnabledBlockConverters ) ) { - Output.get().logInfo( "###### blockConverters: reloadConfig)(: 2"); JsonFileIO jfio = new JsonFileIO(); BlockConvertersData temp = (BlockConvertersData) jfio.readJsonFile( getConfigFile(), getBcData() ); @@ -389,4 +388,59 @@ public List findEventTrigger(RankPlayer rPlaye return eventTriggers; } + /** + *

This function gets all of the blocks within the BlockConverterEventTriggers that should be + * ignored, and removed, from explosion events, or multi-block events. If this feature is + * enabled, then the only way to break those blocks, or to trigger those plugins that + * should handle those blocks, is by direct block breakage, and not explosion events. + *

+ * + *

The list of blocks, should not be impacted by player's permissions because if they are, then + * those who do not have access to those blocks, would then be able to break those blocks, or at least + * through explosion events. + *

+ * + * @param rPlayer + * @return + */ + public List findEventTriggerBlockNames(RankPlayer rPlayer) { + List blockNames = new ArrayList<>(); + + TreeMap eventTriggers = getBcData().getBlockConvertersEventTiggers(); + + Set keys = eventTriggers.keySet(); + for (String key : keys) { + BlockConverterEventTrigger et = eventTriggers.get(key); + + String blockName = et.getKeyBlockName().toLowerCase(); + + // Confirm the player has perms: + if ( et.isEnabled() && + et.getPermissions() != null && et.getPermissions().size() > 0 ) { + + for (String perm : et.getPermissions() ) { + if ( rPlayer.hasPermission( perm ) ) { + + for ( BlockConverterOptionEventTrigger eventTrigger : et.getOptions() ) { + if ( eventTrigger.isIgnoreBlockInExplosionEvents() ) { + + if ( !blockNames.contains(blockName) ) { + + blockNames.add( blockName ); + break; + } + } + } + + } + if ( blockNames.contains(blockName) ) { + break; + } + } + } + } + + return blockNames; + } + } diff --git a/prison-core/src/main/java/tech/mcprison/prison/autofeatures/BlockConvertersInitializer.java b/prison-core/src/main/java/tech/mcprison/prison/autofeatures/BlockConvertersInitializer.java index b1ffd265b..7c9cab93a 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/autofeatures/BlockConvertersInitializer.java +++ b/prison-core/src/main/java/tech/mcprison/prison/autofeatures/BlockConvertersInitializer.java @@ -133,6 +133,10 @@ private void loadDefaultEventTriggers(TreeMap Date: Sun, 17 Sep 2023 10:43:26 -0400 Subject: [PATCH 105/151] BlockConverters EventTriggers - setup the PrisonMinesBlockBreakEvent to allow an event to identify if the primary block must be forcefully removed, which is only used right now with event triggers, and would remove the block when handling a MONITOR event, which normally does not remove any blocks. --- docs/changelog_v3.3.x.md | 11 ++++++++++- .../spigot/api/PrisonMinesBlockBreakEvent.java | 13 +++++++++++++ .../events/AutoManagerBlockBreakEvents.java | 8 ++++++++ 3 files changed, 31 insertions(+), 1 deletion(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index f13bbd989..7252d725f 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -14,7 +14,16 @@ These change logs represent the work that has been going on within prison. -# 3.3.0-alpha.15e 2023-09-16 +# 3.3.0-alpha.15e 2023-09-17 + + +* **BlockConverters EventTriggers - setup the PrisonMinesBlockBreakEvent to allow an event to identify if the primary block must be forcefully removed**, which is only used right now with event triggers, and would remove the block when handling a MONITOR event, which normally does not remove any blocks. + + +* **BlockConverters EventTriggers: Setup more controls within the settings of a blockEvent.** +Setup the ability to control processing of drops: if disabled, it will treat the block event as a MONITOR. This allows the block to be counted correctly. +Setup the ability to ignore the block type within all explosions, so each block would have to be broken individually. +Setup the ability to remove the block without dropping anything since another plugin would have already processed the block, so nothing would remain to be done with it. * **Mines block edit - Found a problem where if you are trying to edit a block and the name does not match, it was causing an error.** Now reports that the block name is invalid. diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/api/PrisonMinesBlockBreakEvent.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/api/PrisonMinesBlockBreakEvent.java index 8c4bd727e..ce5283bbd 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/api/PrisonMinesBlockBreakEvent.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/api/PrisonMinesBlockBreakEvent.java @@ -105,6 +105,12 @@ public class PrisonMinesBlockBreakEvent private boolean forceAutoSell = false; + // If forceBlockRemoval is true, then it will remove the block even if the block + // break priority is MONITOR. This setting is only used (so far) with the + // BlockConverters Event Triggers to bypass prison processing, but will allow prison + // to remove the block and then treat it like a MONITOR event so it gets counted. + private boolean forceBlockRemoval = false; + private BlockBreakPriority bbPriority; @@ -454,6 +460,13 @@ public boolean isForceAutoSell() { public void setForceAutoSell( boolean forceAutoSell ) { this.forceAutoSell = forceAutoSell; } + + public boolean isForceBlockRemoval() { + return forceBlockRemoval; + } + public void setForceBlockRemoval(boolean forceBlockRemoval) { + this.forceBlockRemoval = forceBlockRemoval; + } public BlockBreakPriority getBbPriority() { return bbPriority; diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerBlockBreakEvents.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerBlockBreakEvents.java index 282b1004b..7463a46bd 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerBlockBreakEvents.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerBlockBreakEvents.java @@ -366,6 +366,14 @@ private void handleBlockBreakEvent( BlockBreakEvent e, BlockBreakPriority bbPrio else if ( pmEvent.getBbPriority().isMonitor() ) { // Stop here, and prevent additional processing. // Monitors should never process the event beyond this. + + // NOTE: BlockConverters EventTriggers will force processing to MONITOR + // plus require the block to be removed with no drops with + // no block events. + if ( pmEvent.isForceBlockRemoval() ) { + + finalizeBreakTheBlocks( pmEvent ); + } } From 1b92f1ca3afee41ab0e9913581ca3935bcff1da6 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sun, 17 Sep 2023 10:48:05 -0400 Subject: [PATCH 106/151] BlockConverters EventTriggers: Setup the next phase of handling where blocks in explosions can be ignored. --- docs/changelog_v3.3.x.md | 3 + .../BlockConvertersFileConfig.java | 28 +++---- .../autofeatures/AutoManagerFeatures.java | 74 +++++++++++++++++++ .../events/AutoManagerBlockBreakEvents.java | 9 ++- 4 files changed, 93 insertions(+), 21 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 7252d725f..404eb3083 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -17,6 +17,9 @@ These change logs represent the work that has been going on within prison. # 3.3.0-alpha.15e 2023-09-17 +* **BlockConverters EventTriggers: Setup the next phase of handling where blocks in explosions can be ignored.** + + * **BlockConverters EventTriggers - setup the PrisonMinesBlockBreakEvent to allow an event to identify if the primary block must be forcefully removed**, which is only used right now with event triggers, and would remove the block when handling a MONITOR event, which normally does not remove any blocks. diff --git a/prison-core/src/main/java/tech/mcprison/prison/autofeatures/BlockConvertersFileConfig.java b/prison-core/src/main/java/tech/mcprison/prison/autofeatures/BlockConvertersFileConfig.java index 5bb8ddbd3..5893b8165 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/autofeatures/BlockConvertersFileConfig.java +++ b/prison-core/src/main/java/tech/mcprison/prison/autofeatures/BlockConvertersFileConfig.java @@ -403,7 +403,7 @@ public List findEventTrigger(RankPlayer rPlaye * @param rPlayer * @return */ - public List findEventTriggerBlockNames(RankPlayer rPlayer) { + public List findEventTriggerBlockNames() { List blockNames = new ArrayList<>(); TreeMap eventTriggers = getBcData().getBlockConvertersEventTiggers(); @@ -414,27 +414,17 @@ public List findEventTriggerBlockNames(RankPlayer rPlayer) { String blockName = et.getKeyBlockName().toLowerCase(); - // Confirm the player has perms: - if ( et.isEnabled() && - et.getPermissions() != null && et.getPermissions().size() > 0 ) { + // Confirm the BlockConverter is active: + if ( et.isEnabled() ) { - for (String perm : et.getPermissions() ) { - if ( rPlayer.hasPermission( perm ) ) { + for ( BlockConverterOptionEventTrigger eventTrigger : et.getOptions() ) { + if ( eventTrigger.isIgnoreBlockInExplosionEvents() ) { - for ( BlockConverterOptionEventTrigger eventTrigger : et.getOptions() ) { - if ( eventTrigger.isIgnoreBlockInExplosionEvents() ) { - - if ( !blockNames.contains(blockName) ) { - - blockNames.add( blockName ); - break; - } - } + if ( !blockNames.contains(blockName) ) { + + blockNames.add( blockName ); + break; } - - } - if ( blockNames.contains(blockName) ) { - break; } } } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerFeatures.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerFeatures.java index d1e5ef6f3..9abf35c2a 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerFeatures.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerFeatures.java @@ -8,6 +8,7 @@ import java.util.Map.Entry; import java.util.Random; import java.util.Set; +import java.util.TreeMap; import org.bukkit.Bukkit; import org.bukkit.Material; @@ -3305,6 +3306,11 @@ public boolean checkBlockConverterEventTrigger(PrisonMinesBlockBreakEvent pmEven if ( !eventTrigger.isAllowPrisonToProccessDrops() ) { terminate = true; } + + if ( eventTrigger.isRemoveBlockWithoutDrops() ) { + pmEvent.setForceBlockRemoval( true ); + pmEvent.setBbPriority( BlockBreakPriority.MONITOR ); + } } catch (EventException e) { } @@ -3327,6 +3333,74 @@ public boolean checkBlockConverterEventTrigger(PrisonMinesBlockBreakEvent pmEven return terminate; } + + public void removeEventTriggerBlockksFromExplosions(PrisonMinesBlockBreakEvent pmEvent ) { + + if ( pmEvent.getExplodedBlocks().size() > 0 && + AutoFeaturesWrapper.getBlockConvertersInstance().getBcData().getBlockConvertersEventTiggers().size() > 0 ) { + + long start = System.currentTimeMillis(); + + RankPlayer rPlayer = PrisonRanks.getInstance().getPlayerManager().getPlayer( pmEvent.getSpigotPlayer() ); + + + List blockNamesToRemove = AutoFeaturesWrapper.getBlockConvertersInstance().findEventTriggerBlockNames( rPlayer ); + List removeBlocks = new ArrayList<>(); + TreeMap blockCounts = new TreeMap<>(); + + for (SpigotBlock explodedBlock : pmEvent.getExplodedBlocks()) { + String blockName = explodedBlock.getBlockName().toLowerCase(); + if ( blockNamesToRemove.contains( blockName ) ) { + removeBlocks.add( explodedBlock ); + + if ( !blockCounts.containsKey(blockName) ) { + blockCounts.put( blockName, 1 ); + } + else { + int count = blockCounts.get( blockName ); + blockCounts.put( blockName, ++count ); + } + } + } + + if ( removeBlocks.size() > 0 ) { + pmEvent.getExplodedBlocks().removeAll( removeBlocks ); + } + + + long stop = System.currentTimeMillis(); + double durationMs = (stop - start) / 1_000_000.0d; + + + // Log if blocks were removed, or if duration is >= 0.5: + if ( removeBlocks.size() > 0 || durationMs > 0.5 ) { + + StringBuilder sb = new StringBuilder(); + + Set keys = blockCounts.keySet(); + for (String key : keys) { + if ( sb.length() > 0 ) { + sb.append(","); + } + sb.append( key ).append( ":" ).append( blockCounts.get(key).toString() ); + } + + if ( sb.length() == 0 ) { + sb.append( "none" ); + } + DecimalFormat dFmt = new DecimalFormat( "#,##0.000" ); + + String msg = String.format( + "(BlockConverter eventTrigger: blocks removed: [%s] %s ms) ", + sb, + dFmt.format( durationMs ) ); + pmEvent.getDebugInfo().append( msg ); + } + + } + + } + private RegisteredListener findBlockBreakEventListener( String plugin, String priority, String className ) { RegisteredListener results = null; diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerBlockBreakEvents.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerBlockBreakEvents.java index 7463a46bd..e116f6d79 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerBlockBreakEvents.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerBlockBreakEvents.java @@ -337,12 +337,17 @@ private void handleBlockBreakEvent( BlockBreakEvent e, BlockBreakPriority bbPrio // Check for BlockConverters Event Triggers: + // If this function returns a true, then the event should be canceled so no other plugins + // process the block after the triggered plugin has processed it. + // If the eventTrigger is marked to remove block without drops, then the + // block break event priority will be set to MONITOR and will force the + // block to be removed by prison. if ( checkBlockConverterEventTrigger( pmEvent, e ) ) { e.setCancelled( true ); - printDebugInfo( pmEvent, start ); - return; +// printDebugInfo( pmEvent, start ); +// return; } From 1b1df8a678008aa2fbe07ec1a3b552ef91a2e74a Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sun, 17 Sep 2023 10:54:22 -0400 Subject: [PATCH 107/151] BlockConverters eventTriggers: Add the support for explosion events to all of the explosion event handlers. --- docs/changelog_v3.3.x.md | 3 +++ .../spigot/autofeatures/AutoManagerFeatures.java | 2 +- .../autofeatures/events/AutoManagerCrazyEnchants.java | 7 +++++++ .../autofeatures/events/AutoManagerPrisonEnchants.java | 7 +++++++ .../AutoManagerPrisonsExplosiveBlockBreakEvents.java | 8 ++++++++ .../events/AutoManagerRevEnchantsExplosiveEvent.java | 8 ++++++++ .../events/AutoManagerRevEnchantsJackHammerEvent.java | 8 ++++++++ .../autofeatures/events/AutoManagerTokenEnchant.java | 10 ++++++++++ .../AutoManagerXPrisonExplosionTriggerEvent.java | 9 +++++++++ .../events/AutoManagerXPrisonLayerTriggerEvent.java | 8 ++++++++ .../events/AutoManagerXPrisonNukeTriggerEvent.java | 10 ++++++++++ .../autofeatures/events/AutoManagerZenchantments.java | 8 ++++++++ 12 files changed, 87 insertions(+), 1 deletion(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 404eb3083..953fc10be 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -17,6 +17,9 @@ These change logs represent the work that has been going on within prison. # 3.3.0-alpha.15e 2023-09-17 +* **BlockConverters eventTriggers: Add the support for explosion events to all of the explosion event handlers.** + + * **BlockConverters EventTriggers: Setup the next phase of handling where blocks in explosions can be ignored.** diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerFeatures.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerFeatures.java index 9abf35c2a..ae4895c47 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerFeatures.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerFeatures.java @@ -3344,7 +3344,7 @@ public void removeEventTriggerBlockksFromExplosions(PrisonMinesBlockBreakEvent p RankPlayer rPlayer = PrisonRanks.getInstance().getPlayerManager().getPlayer( pmEvent.getSpigotPlayer() ); - List blockNamesToRemove = AutoFeaturesWrapper.getBlockConvertersInstance().findEventTriggerBlockNames( rPlayer ); + List blockNamesToRemove = AutoFeaturesWrapper.getBlockConvertersInstance().findEventTriggerBlockNames(); List removeBlocks = new ArrayList<>(); TreeMap blockCounts = new TreeMap<>(); diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerCrazyEnchants.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerCrazyEnchants.java index 0337dfa4c..1cadcab4a 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerCrazyEnchants.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerCrazyEnchants.java @@ -341,6 +341,13 @@ public void handleBlastUseEvent( BlastUseEvent e, BlockBreakPriority bbPriority } + // Check to see if the blockConverter's EventTrigger should have + // it's blocks suppressed from explosion events. If they should be + // removed, then it's removed within this funciton. + removeEventTriggerBlockksFromExplosions( pmEvent ); + + + if ( !validateEvent( pmEvent ) ) { // The event has not passed validation. All logging and Errors have been recorded diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerPrisonEnchants.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerPrisonEnchants.java index 6fae4927b..e7089f9d8 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerPrisonEnchants.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerPrisonEnchants.java @@ -330,6 +330,13 @@ public void handlePEExplosionEvent( PEExplosionEvent e, BlockBreakPriority bbPri pmEvent.setUnprocessedRawBlocks( e.getExplodedBlocks() ); + // Check to see if the blockConverter's EventTrigger should have + // it's blocks suppressed from explosion events. If they should be + // removed, then it's removed within this funciton. + removeEventTriggerBlockksFromExplosions( pmEvent ); + + + if ( !validateEvent( pmEvent ) ) { // The event has not passed validation. All logging and Errors have been recorded diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerPrisonsExplosiveBlockBreakEvents.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerPrisonsExplosiveBlockBreakEvents.java index 28788f1dc..e603e1cff 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerPrisonsExplosiveBlockBreakEvents.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerPrisonsExplosiveBlockBreakEvents.java @@ -328,6 +328,14 @@ protected void handleExplosiveBlockBreakEvent( ExplosiveBlockBreakEvent e, pmEvent.setForceAutoSell( e.getMineBomb().isAutosell() ); } + + // Check to see if the blockConverter's EventTrigger should have + // it's blocks suppressed from explosion events. If they should be + // removed, then it's removed within this funciton. + removeEventTriggerBlockksFromExplosions( pmEvent ); + + + if ( !validateEvent( pmEvent ) ) { // The event has not passed validation. All logging and Errors have been recorded diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerRevEnchantsExplosiveEvent.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerRevEnchantsExplosiveEvent.java index c04881870..1ab8a9166 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerRevEnchantsExplosiveEvent.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerRevEnchantsExplosiveEvent.java @@ -341,6 +341,14 @@ public void handleRevEnchantsExplosiveEvent( ExplosiveEvent e, BlockBreakPriorit } + + // Check to see if the blockConverter's EventTrigger should have + // it's blocks suppressed from explosion events. If they should be + // removed, then it's removed within this funciton. + removeEventTriggerBlockksFromExplosions( pmEvent ); + + + if ( !validateEvent( pmEvent ) ) { // The event has not passed validation. All logging and Errors have been recorded diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerRevEnchantsJackHammerEvent.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerRevEnchantsJackHammerEvent.java index 8aac7fa3c..d4bca61e9 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerRevEnchantsJackHammerEvent.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerRevEnchantsJackHammerEvent.java @@ -367,6 +367,14 @@ public void handleRevEnchantsJackHammerEvent( JackHammerEvent e, BlockBreakPrior // pmEvent.getUnprocessedRawBlocks().add( blocks.get( i ) ); // } + + + // Check to see if the blockConverter's EventTrigger should have + // it's blocks suppressed from explosion events. If they should be + // removed, then it's removed within this funciton. + removeEventTriggerBlockksFromExplosions( pmEvent ); + + if ( !validateEvent( pmEvent ) ) { diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerTokenEnchant.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerTokenEnchant.java index 782ca8d81..ea5ebf6c9 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerTokenEnchant.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerTokenEnchant.java @@ -395,6 +395,16 @@ public void handleTEBlockExplodeEvent( TEBlockExplodeEvent e, BlockBreakPriority pmEvent.setUnprocessedRawBlocks( e.blockList() ); + + + // Check to see if the blockConverter's EventTrigger should have + // it's blocks suppressed from explosion events. If they should be + // removed, then it's removed within this funciton. + removeEventTriggerBlockksFromExplosions( pmEvent ); + + + + if ( !validateEvent( pmEvent ) ) { // The event has not passed validation. All logging and Errors have been recorded diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerXPrisonExplosionTriggerEvent.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerXPrisonExplosionTriggerEvent.java index 2fa73f1ee..33a8d9fee 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerXPrisonExplosionTriggerEvent.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerXPrisonExplosionTriggerEvent.java @@ -350,6 +350,15 @@ public void handleXPrisonExplosionTriggerEvent( ExplosionTriggerEvent e, BlockBr } + + + // Check to see if the blockConverter's EventTrigger should have + // it's blocks suppressed from explosion events. If they should be + // removed, then it's removed within this funciton. + removeEventTriggerBlockksFromExplosions( pmEvent ); + + + if ( !validateEvent( pmEvent ) ) { // The event has not passed validation. All logging and Errors have been recorded diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerXPrisonLayerTriggerEvent.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerXPrisonLayerTriggerEvent.java index 49a292082..943d97944 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerXPrisonLayerTriggerEvent.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerXPrisonLayerTriggerEvent.java @@ -350,6 +350,14 @@ public void handleXPrisonLayerTriggerEvent( LayerTriggerEvent e, BlockBreakPrior } + + // Check to see if the blockConverter's EventTrigger should have + // it's blocks suppressed from explosion events. If they should be + // removed, then it's removed within this funciton. + removeEventTriggerBlockksFromExplosions( pmEvent ); + + + if ( !validateEvent( pmEvent ) ) { // The event has not passed validation. All logging and Errors have been recorded diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerXPrisonNukeTriggerEvent.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerXPrisonNukeTriggerEvent.java index 6ce8ac71f..febd42295 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerXPrisonNukeTriggerEvent.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerXPrisonNukeTriggerEvent.java @@ -350,6 +350,16 @@ public void handleXPrisonNukeTriggerEvent( NukeTriggerEvent e, BlockBreakPriorit } + + + // Check to see if the blockConverter's EventTrigger should have + // it's blocks suppressed from explosion events. If they should be + // removed, then it's removed within this funciton. + removeEventTriggerBlockksFromExplosions( pmEvent ); + + + + if ( !validateEvent( pmEvent ) ) { // The event has not passed validation. All logging and Errors have been recorded diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerZenchantments.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerZenchantments.java index ed0f54a57..528e355e9 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerZenchantments.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerZenchantments.java @@ -328,6 +328,14 @@ private void handleZenchantmentsBlockBreakEvent( BlockBreakEvent e, BlockBreakPr } + + // Check to see if the blockConverter's EventTrigger should have + // it's blocks suppressed from explosion events. If they should be + // removed, then it's removed within this funciton. + removeEventTriggerBlockksFromExplosions( pmEvent ); + + + if ( !validateEvent( pmEvent ) ) { // The event has not passed validation. All logging and Errors have been recorded From 0e16217bc62e4a7bceda95f7240d1f069762524a Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sun, 17 Sep 2023 10:58:31 -0400 Subject: [PATCH 108/151] SpigotPlayer: fixed a problem where the object was expected to be comparable. --- docs/changelog_v3.3.x.md | 3 +++ .../tech/mcprison/prison/spigot/game/SpigotPlayer.java | 8 +++++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 953fc10be..a4629dfcd 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -17,6 +17,9 @@ These change logs represent the work that has been going on within prison. # 3.3.0-alpha.15e 2023-09-17 +* **SpigotPlayer: fixed a problem where the object was expected to be comparable.** + + * **BlockConverters eventTriggers: Add the support for explosion events to all of the explosion event handlers.** diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotPlayer.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotPlayer.java index 47157a008..bb671acd4 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotPlayer.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotPlayer.java @@ -62,7 +62,7 @@ */ public class SpigotPlayer extends SpigotCommandSender - implements Player { + implements Player, Comparable { private RankPlayer rankPlayer; @@ -306,6 +306,12 @@ public SpigotPlayerInventory getSpigotPlayerInventory() { // return results; // } + @Override + public int compareTo( SpigotPlayer sPlayer) { + return getName().compareTo( sPlayer.getName() ); + } + + @Override public String toString() { StringBuilder sb = new StringBuilder(); From ed2b9f40d2673b0b5858265351f6bc2041e2a06e Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sun, 17 Sep 2023 10:59:59 -0400 Subject: [PATCH 109/151] Sellall command: '/sellall set delay' - fixed the description which had a typo in the description. --- .../prison/spigot/commands/PrisonSpigotSellAllCommands.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/commands/PrisonSpigotSellAllCommands.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/commands/PrisonSpigotSellAllCommands.java index 3592afc3b..a81943f1f 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/commands/PrisonSpigotSellAllCommands.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/commands/PrisonSpigotSellAllCommands.java @@ -106,12 +106,14 @@ private void sellAllCommands(CommandSender sender) { } @Command(identifier = "sellall set delay", - description = "Enables or disables a SellAll cooldown delay to preventh " + description = "Enables or disables a SellAll cooldown delay to prevent " + "players from spamming the sellall command. " + "See `/sellall set delayTime`.", onlyPlayers = false, permissions = "prison.sellall.delay") private void sellAllDelay(CommandSender sender, - @Arg(name = "boolean", description = "True to enable or false to disable.", def = "false") String enable){ + @Arg(name = "boolean", + description = "True to enable or false to disable.", + def = "false") String enable){ if (!isEnabled()) return; From 972851cb2521627ac791a9a4a155e58d40d61679 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sun, 17 Sep 2023 11:32:13 -0400 Subject: [PATCH 110/151] BlockConverters eventTriggers: Fixed the handling of event trigger blocks so they can be ignored within an explosion event. Now works. Still have to process the event trigger blocks in explosions for when they need to be triggered. --- docs/changelog_v3.3.x.md | 7 +++++++ .../autofeatures/AutoManagerFeatures.java | 21 +++++++++++-------- 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index a4629dfcd..c71c15411 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -17,6 +17,13 @@ These change logs represent the work that has been going on within prison. # 3.3.0-alpha.15e 2023-09-17 +* **BlockConverters eventTriggers: Fixed the handling of event trigger blocks so they can be ignored within an explosion event. Now works.** +Still have to process the event trigger blocks in explosions for when they need to be triggered. + + +* **Sellall command: '/sellall set delay' - fixed the description which had a typo in the description.** + + * **SpigotPlayer: fixed a problem where the object was expected to be comparable.** diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerFeatures.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerFeatures.java index ae4895c47..71b46d3df 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerFeatures.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerFeatures.java @@ -3336,22 +3336,25 @@ public boolean checkBlockConverterEventTrigger(PrisonMinesBlockBreakEvent pmEven public void removeEventTriggerBlockksFromExplosions(PrisonMinesBlockBreakEvent pmEvent ) { - if ( pmEvent.getExplodedBlocks().size() > 0 && + if ( pmEvent.getUnprocessedRawBlocks().size() > 0 && AutoFeaturesWrapper.getBlockConvertersInstance().getBcData().getBlockConvertersEventTiggers().size() > 0 ) { long start = System.currentTimeMillis(); - RankPlayer rPlayer = PrisonRanks.getInstance().getPlayerManager().getPlayer( pmEvent.getSpigotPlayer() ); +// RankPlayer rPlayer = PrisonRanks.getInstance().getPlayerManager().getPlayer( pmEvent.getSpigotPlayer() ); - List blockNamesToRemove = AutoFeaturesWrapper.getBlockConvertersInstance().findEventTriggerBlockNames(); - List removeBlocks = new ArrayList<>(); TreeMap blockCounts = new TreeMap<>(); + + List blockNamesToRemove = AutoFeaturesWrapper.getBlockConvertersInstance().findEventTriggerBlockNames(); + List removeBlocks = new ArrayList<>(); - for (SpigotBlock explodedBlock : pmEvent.getExplodedBlocks()) { - String blockName = explodedBlock.getBlockName().toLowerCase(); + for (Block block : pmEvent.getUnprocessedRawBlocks()) { + SpigotBlock sBlock = SpigotBlock.getSpigotBlock( block ); + String blockName = sBlock.getBlockName().toLowerCase(); + if ( blockNamesToRemove.contains( blockName ) ) { - removeBlocks.add( explodedBlock ); + removeBlocks.add( block ); if ( !blockCounts.containsKey(blockName) ) { blockCounts.put( blockName, 1 ); @@ -3364,7 +3367,7 @@ public void removeEventTriggerBlockksFromExplosions(PrisonMinesBlockBreakEvent p } if ( removeBlocks.size() > 0 ) { - pmEvent.getExplodedBlocks().removeAll( removeBlocks ); + pmEvent.getUnprocessedRawBlocks().removeAll( removeBlocks ); } @@ -3373,7 +3376,7 @@ public void removeEventTriggerBlockksFromExplosions(PrisonMinesBlockBreakEvent p // Log if blocks were removed, or if duration is >= 0.5: - if ( removeBlocks.size() > 0 || durationMs > 0.5 ) { + if ( blockCounts.size() > 0 || durationMs > 0.5 ) { StringBuilder sb = new StringBuilder(); From 38178e1a6fc54d187844c0703055a718259e4c82 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Tue, 19 Sep 2023 23:29:40 -0400 Subject: [PATCH 111/151] Block Converters: event triggers: More work. Got it working to the point that it's ready for production. The way it is right now, any block that is in an event trigger, will be excluded from all explosions. They will remain unbroken in the mine. The players can then break them directly to trigger the events. Eventually I may allow processing within an explosion event, but right now it's not making sense to process 100+ triggers all at one time for huge explosions... the other plugin that's being "fired" may cause lag trying to process that many at one time. --- docs/changelog_v3.3.x.md | 8 ++++++- .../BlockConvertersFileConfig.java | 23 +++++++++++++++++- .../autofeatures/AutoManagerFeatures.java | 22 ++++++++++++++--- .../events/AutoManagerCrazyEnchants.java | 2 +- .../events/AutoManagerPrisonEnchants.java | 2 +- ...nagerPrisonsExplosiveBlockBreakEvents.java | 2 +- .../AutoManagerRevEnchantsExplosiveEvent.java | 2 +- ...AutoManagerRevEnchantsJackHammerEvent.java | 2 +- .../events/AutoManagerTokenEnchant.java | 2 +- ...toManagerXPrisonExplosionTriggerEvent.java | 2 +- .../AutoManagerXPrisonLayerTriggerEvent.java | 2 +- .../AutoManagerXPrisonNukeTriggerEvent.java | 2 +- .../events/AutoManagerZenchantments.java | 2 +- .../spigot/block/OnBlockBreakEventCore.java | 24 +++++++++++++++++++ 14 files changed, 82 insertions(+), 15 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index c71c15411..e2be5f3ae 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -14,7 +14,13 @@ These change logs represent the work that has been going on within prison. -# 3.3.0-alpha.15e 2023-09-17 +# 3.3.0-alpha.15e 2023-09-19 + + +* **Block Converters: event triggers: More work. Got it working to the point that it's ready for production.** +The way it is right now, any block that is in an event trigger, will be excluded from all explosions. They will remain unbroken in the mine. +The players can then break them directly to trigger the events. Eventually I may allow processing within an explosion event, but right now it's not making sense to process 100+ triggers all at one time for huge explosions... the other plugin that's being "fired" may cause lag trying to process that many at one time. + * **BlockConverters eventTriggers: Fixed the handling of event trigger blocks so they can be ignored within an explosion event. Now works.** diff --git a/prison-core/src/main/java/tech/mcprison/prison/autofeatures/BlockConvertersFileConfig.java b/prison-core/src/main/java/tech/mcprison/prison/autofeatures/BlockConvertersFileConfig.java index 5893b8165..9aee09d88 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/autofeatures/BlockConvertersFileConfig.java +++ b/prison-core/src/main/java/tech/mcprison/prison/autofeatures/BlockConvertersFileConfig.java @@ -22,6 +22,7 @@ public class BlockConvertersFileConfig { private transient BlockConvertersData bcData; + private transient List eventTriggerBlockNames; // private TreeMap> blockConverters; // private TreeMap blockConvertersEventTiggers; @@ -43,6 +44,8 @@ public BlockConvertersFileConfig() { this.bcData = new BlockConvertersData(); + this.eventTriggerBlockNames = null; + // this.blockConverters = new TreeMap<>(); // this.blockConvertersEventTiggers = new TreeMap<>(); // @@ -279,6 +282,9 @@ public Boolean isProcessAutoFeaturesAllBlocks( RankPlayer player ) { private boolean initialConfig() { boolean dirty = false; + // Set to null so it will auto reload on next access: + setEventTriggerBlockNames( null ); + BlockConvertersInitializer initializer = new BlockConvertersInitializer(); boolean d1 = initializer.checkConfigs( getBcData().getBlockConverters() ); @@ -388,6 +394,21 @@ public List findEventTrigger(RankPlayer rPlaye return eventTriggers; } + + + + public List getEventTriggerBlockNames() { + + if ( eventTriggerBlockNames == null ) { + eventTriggerBlockNames = findEventTriggerBlockNames(); + } + return eventTriggerBlockNames; + } + + public void setEventTriggerBlockNames(List eventTriggerBlockNames) { + this.eventTriggerBlockNames = eventTriggerBlockNames; + } + /** *

This function gets all of the blocks within the BlockConverterEventTriggers that should be * ignored, and removed, from explosion events, or multi-block events. If this feature is @@ -403,7 +424,7 @@ public List findEventTrigger(RankPlayer rPlaye * @param rPlayer * @return */ - public List findEventTriggerBlockNames() { + private List findEventTriggerBlockNames() { List blockNames = new ArrayList<>(); TreeMap eventTriggers = getBcData().getBlockConvertersEventTiggers(); diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerFeatures.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerFeatures.java index 71b46d3df..56e8db5ee 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerFeatures.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerFeatures.java @@ -3310,6 +3310,8 @@ public boolean checkBlockConverterEventTrigger(PrisonMinesBlockBreakEvent pmEven if ( eventTrigger.isRemoveBlockWithoutDrops() ) { pmEvent.setForceBlockRemoval( true ); pmEvent.setBbPriority( BlockBreakPriority.MONITOR ); + + finalizeBreakTheBlocks( pmEvent, pmEvent.getSpigotBlock(), pmEvent.getTargetBlock() ); } } catch (EventException e) { @@ -3333,11 +3335,17 @@ public boolean checkBlockConverterEventTrigger(PrisonMinesBlockBreakEvent pmEven return terminate; } + + public void removeBlockForTriggerEvent( PrisonMinesBlockBreakEvent pmEvent) { + + finalizeBreakTheBlocks( pmEvent ); + + } - public void removeEventTriggerBlockksFromExplosions(PrisonMinesBlockBreakEvent pmEvent ) { + public void removeEventTriggerBlocksFromExplosions( PrisonMinesBlockBreakEvent pmEvent ) { if ( pmEvent.getUnprocessedRawBlocks().size() > 0 && - AutoFeaturesWrapper.getBlockConvertersInstance().getBcData().getBlockConvertersEventTiggers().size() > 0 ) { + AutoFeaturesWrapper.getBlockConvertersInstance().getEventTriggerBlockNames().size() > 0 ) { long start = System.currentTimeMillis(); @@ -3346,7 +3354,7 @@ public void removeEventTriggerBlockksFromExplosions(PrisonMinesBlockBreakEvent p TreeMap blockCounts = new TreeMap<>(); - List blockNamesToRemove = AutoFeaturesWrapper.getBlockConvertersInstance().findEventTriggerBlockNames(); + List blockNamesToRemove = AutoFeaturesWrapper.getBlockConvertersInstance().getEventTriggerBlockNames(); List removeBlocks = new ArrayList<>(); for (Block block : pmEvent.getUnprocessedRawBlocks()) { @@ -3368,6 +3376,14 @@ public void removeEventTriggerBlockksFromExplosions(PrisonMinesBlockBreakEvent p if ( removeBlocks.size() > 0 ) { pmEvent.getUnprocessedRawBlocks().removeAll( removeBlocks ); + + +// if ( eventTrigger.isRemoveBlockWithoutDrops() ) { +//// pmEvent.setForceBlockRemoval( true ); +//// pmEvent.setBbPriority( BlockBreakPriority.MONITOR ); +// +// finalizeBreakTheBlocks( pmEvent, pmEvent.getSpigotBlock(), pmEvent.getTargetBlock() ); +// } } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerCrazyEnchants.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerCrazyEnchants.java index 1cadcab4a..2a0c9ff00 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerCrazyEnchants.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerCrazyEnchants.java @@ -344,7 +344,7 @@ public void handleBlastUseEvent( BlastUseEvent e, BlockBreakPriority bbPriority // Check to see if the blockConverter's EventTrigger should have // it's blocks suppressed from explosion events. If they should be // removed, then it's removed within this funciton. - removeEventTriggerBlockksFromExplosions( pmEvent ); + removeEventTriggerBlocksFromExplosions( pmEvent ); diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerPrisonEnchants.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerPrisonEnchants.java index e7089f9d8..f3b5359fe 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerPrisonEnchants.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerPrisonEnchants.java @@ -333,7 +333,7 @@ public void handlePEExplosionEvent( PEExplosionEvent e, BlockBreakPriority bbPri // Check to see if the blockConverter's EventTrigger should have // it's blocks suppressed from explosion events. If they should be // removed, then it's removed within this funciton. - removeEventTriggerBlockksFromExplosions( pmEvent ); + removeEventTriggerBlocksFromExplosions( pmEvent ); diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerPrisonsExplosiveBlockBreakEvents.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerPrisonsExplosiveBlockBreakEvents.java index e603e1cff..20680ca16 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerPrisonsExplosiveBlockBreakEvents.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerPrisonsExplosiveBlockBreakEvents.java @@ -332,7 +332,7 @@ protected void handleExplosiveBlockBreakEvent( ExplosiveBlockBreakEvent e, // Check to see if the blockConverter's EventTrigger should have // it's blocks suppressed from explosion events. If they should be // removed, then it's removed within this funciton. - removeEventTriggerBlockksFromExplosions( pmEvent ); + removeEventTriggerBlocksFromExplosions( pmEvent ); diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerRevEnchantsExplosiveEvent.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerRevEnchantsExplosiveEvent.java index 1ab8a9166..595c9291a 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerRevEnchantsExplosiveEvent.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerRevEnchantsExplosiveEvent.java @@ -345,7 +345,7 @@ public void handleRevEnchantsExplosiveEvent( ExplosiveEvent e, BlockBreakPriorit // Check to see if the blockConverter's EventTrigger should have // it's blocks suppressed from explosion events. If they should be // removed, then it's removed within this funciton. - removeEventTriggerBlockksFromExplosions( pmEvent ); + removeEventTriggerBlocksFromExplosions( pmEvent ); diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerRevEnchantsJackHammerEvent.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerRevEnchantsJackHammerEvent.java index d4bca61e9..6af193697 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerRevEnchantsJackHammerEvent.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerRevEnchantsJackHammerEvent.java @@ -372,7 +372,7 @@ public void handleRevEnchantsJackHammerEvent( JackHammerEvent e, BlockBreakPrior // Check to see if the blockConverter's EventTrigger should have // it's blocks suppressed from explosion events. If they should be // removed, then it's removed within this funciton. - removeEventTriggerBlockksFromExplosions( pmEvent ); + removeEventTriggerBlocksFromExplosions( pmEvent ); diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerTokenEnchant.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerTokenEnchant.java index ea5ebf6c9..5ea2ff076 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerTokenEnchant.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerTokenEnchant.java @@ -400,7 +400,7 @@ public void handleTEBlockExplodeEvent( TEBlockExplodeEvent e, BlockBreakPriority // Check to see if the blockConverter's EventTrigger should have // it's blocks suppressed from explosion events. If they should be // removed, then it's removed within this funciton. - removeEventTriggerBlockksFromExplosions( pmEvent ); + removeEventTriggerBlocksFromExplosions( pmEvent ); diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerXPrisonExplosionTriggerEvent.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerXPrisonExplosionTriggerEvent.java index 33a8d9fee..758d082b0 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerXPrisonExplosionTriggerEvent.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerXPrisonExplosionTriggerEvent.java @@ -355,7 +355,7 @@ public void handleXPrisonExplosionTriggerEvent( ExplosionTriggerEvent e, BlockBr // Check to see if the blockConverter's EventTrigger should have // it's blocks suppressed from explosion events. If they should be // removed, then it's removed within this funciton. - removeEventTriggerBlockksFromExplosions( pmEvent ); + removeEventTriggerBlocksFromExplosions( pmEvent ); diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerXPrisonLayerTriggerEvent.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerXPrisonLayerTriggerEvent.java index 943d97944..6043f5a2b 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerXPrisonLayerTriggerEvent.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerXPrisonLayerTriggerEvent.java @@ -354,7 +354,7 @@ public void handleXPrisonLayerTriggerEvent( LayerTriggerEvent e, BlockBreakPrior // Check to see if the blockConverter's EventTrigger should have // it's blocks suppressed from explosion events. If they should be // removed, then it's removed within this funciton. - removeEventTriggerBlockksFromExplosions( pmEvent ); + removeEventTriggerBlocksFromExplosions( pmEvent ); diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerXPrisonNukeTriggerEvent.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerXPrisonNukeTriggerEvent.java index febd42295..2185fc3d5 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerXPrisonNukeTriggerEvent.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerXPrisonNukeTriggerEvent.java @@ -355,7 +355,7 @@ public void handleXPrisonNukeTriggerEvent( NukeTriggerEvent e, BlockBreakPriorit // Check to see if the blockConverter's EventTrigger should have // it's blocks suppressed from explosion events. If they should be // removed, then it's removed within this funciton. - removeEventTriggerBlockksFromExplosions( pmEvent ); + removeEventTriggerBlocksFromExplosions( pmEvent ); diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerZenchantments.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerZenchantments.java index 528e355e9..23bfb8643 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerZenchantments.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerZenchantments.java @@ -332,7 +332,7 @@ private void handleZenchantmentsBlockBreakEvent( BlockBreakEvent e, BlockBreakPr // Check to see if the blockConverter's EventTrigger should have // it's blocks suppressed from explosion events. If they should be // removed, then it's removed within this funciton. - removeEventTriggerBlockksFromExplosions( pmEvent ); + removeEventTriggerBlocksFromExplosions( pmEvent ); diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/block/OnBlockBreakEventCore.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/block/OnBlockBreakEventCore.java index 726a1bfd0..c4264bb6c 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/block/OnBlockBreakEventCore.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/block/OnBlockBreakEventCore.java @@ -326,6 +326,30 @@ private List finalizeBreakTheBlocksCollectEm( PrisonMinesBlockBreak return blocks; } + + /** + *

Used with BlockConverters event triggers. + *

+ * + * @param pmEvent + * @param minedBlock + * @param targetBlock + * @return + */ + protected SpigotBlock finalizeBreakTheBlocks( PrisonMinesBlockBreakEvent pmEvent, + SpigotBlock minedBlock, MineTargetPrisonBlock targetBlock ) { + SpigotBlock results = null; + + if ( targetBlock.getPrisonBlock().getBlockName().equalsIgnoreCase( minedBlock.getBlockName() ) ) { + results = minedBlock; + targetBlock.setAirBroke( true ); + + // Count the blocks that were mined: + countBlocksMined( pmEvent, pmEvent.getTargetBlock() ); + } + + return results; + } /** From 5c73ba586d9f3d84b758eb42b3f0aa70c097f18a Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Thu, 21 Sep 2023 22:20:44 -0400 Subject: [PATCH 112/151] Update the Double vs BigDecimal example. Increased from 25 to 35 iterations, and expanded all columns to adjust for the wider output. --- docs/changelog_v3.3.x.md | 5 ++++- .../prison/util/ExampleJavaDoubleVsBigDecimal.java | 13 +++++++------ 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index e2be5f3ae..1a28d4f35 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -14,7 +14,10 @@ These change logs represent the work that has been going on within prison. -# 3.3.0-alpha.15e 2023-09-19 +# 3.3.0-alpha.15e 2023-09-21 + + +* **Update the Double vs BigDecimal example. Increased from 25 to 35 iterations, and expanded all columns to adjust for the wider output.** * **Block Converters: event triggers: More work. Got it working to the point that it's ready for production.** diff --git a/prison-core/src/main/java/tech/mcprison/prison/util/ExampleJavaDoubleVsBigDecimal.java b/prison-core/src/main/java/tech/mcprison/prison/util/ExampleJavaDoubleVsBigDecimal.java index 5f59bfc4e..ec35b5650 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/util/ExampleJavaDoubleVsBigDecimal.java +++ b/prison-core/src/main/java/tech/mcprison/prison/util/ExampleJavaDoubleVsBigDecimal.java @@ -13,7 +13,7 @@ public static void main( String[] args ) { ArrayList out = app.runSample(); String header = String.format( - "%s %30s %35s %16s %s", + "%s %45s %55s %35s %s", "Int Digits ", " double ", " BigDecimal ", @@ -35,8 +35,9 @@ private ArrayList runSample() { sb.append( ".111111" ); DecimalFormat dFmt = new DecimalFormat( "#,##0.00000" ); +// DecimalFormat iFmt = new DecimalFormat( "#,##0.00000" ); - for ( int i = 1; i < 25; i++ ) { + for ( int i = 1; i < 35; i++ ) { sb.insert( 0, "1" ); double dub = Double.parseDouble( sb.toString() ); @@ -45,12 +46,12 @@ private ArrayList runSample() { BigDecimal delta = bigD.subtract( BigDecimal.valueOf(dub) ); String rpt = String.format( - "%2d %40s %35s %16s %2d", + "%3d %55s %55s %35s %3d", i, dFmt.format( dub ), - bigD.toString(), delta.toString(), - i - ); + dFmt.format( bigD ), + dFmt.format( delta ), + i ); out.add( rpt ); From 54ecf984656d96ac48f16a05c73374ef45e0190f Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Thu, 21 Sep 2023 22:24:22 -0400 Subject: [PATCH 113/151] Ranks Ladder resetRankCost: Added a new parameter to provide an exponent which is used as a Math.pow() function over the base rank cost calculations. This can help increase the rank costs for higher ranks. Default value is 1.0 so it does not apply unless it is specifically changed. --- docs/changelog_v3.3.x.md | 5 +++++ .../prison/ranks/commands/LadderCommands.java | 21 ++++++++++++++++--- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 1a28d4f35..3939a32f6 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -17,6 +17,11 @@ These change logs represent the work that has been going on within prison. # 3.3.0-alpha.15e 2023-09-21 +* **Ranks Ladder resetRankCost: Added a new parameter to provide an exponent which is used as a Math.pow() function over the base rank cost calculations.** +This can help increase the rank costs for higher ranks. +Default value is 1.0 so it does not apply unless it is specifically changed. + + * **Update the Double vs BigDecimal example. Increased from 25 to 35 iterations, and expanded all columns to adjust for the wider output.** diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/LadderCommands.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/LadderCommands.java index f6ecf8139..abd6901ac 100644 --- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/LadderCommands.java +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/LadderCommands.java @@ -546,7 +546,16 @@ public void ladderResetRankCosts(CommandSender sender, + "additional multiplier being multiplied against that value. " + "So for default values for a rankk in the third position, " + "with a 1.75 multipler will have a " - + "cost = 1_000_000_000 * 3 * 1.75.") double addMult ) { + + "cost = 1_000_000_000 * 3 * 1.75.") double addMult, + @Arg(name = "exponent", def = "1", verifiers = "min[0.00001]", + description = "See the cost formula for the 'addMult' parameter. " + + "This parameter adds an exponent to the formula. For a linear " + + "rank cost, use a value of 1.0 for this parameter. Use a value " + + "greater than 1.0, such as 1.2 for slightly more agressive cost " + + "calculation. Since cost is a IEEE double, there is a risk of " + + "lost precision with numbers greater than 16 digits. " + + "cost = (initialCost * rankPosition * addMult)^exponent.") + double exponent ) { LadderManager lm = PrisonRanks.getInstance().getLadderManager(); @@ -559,6 +568,12 @@ public void ladderResetRankCosts(CommandSender sender, return; } + + if ( exponent <= 0 ) { + sender.sendMessage("Error: ranks ladder resetRankCosts: Exponent parameter must be greater than zero."); + return; + } + // Force a backup: PrisonBackups prisonBackup = new PrisonBackups(); @@ -573,10 +588,10 @@ public void ladderResetRankCosts(CommandSender sender, int ranksChanged = 0; - int i = 0; + int i = 1; for (Rank rank : ladder.getRanks() ) { - double cost = initialCost * (i++ + 1) * addMult; + double cost = Math.pow(initialCost * i++ * addMult, exponent ); if ( rank.getRawRankCost() != cost ) { rank.setRawRankCost( cost ); From 1a1aa37c7fe3311d873d744c899865acea03fbcc Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Thu, 21 Sep 2023 22:32:43 -0400 Subject: [PATCH 114/151] Update the Double vs BigDecimal example. More adjustments to the formatting. --- .../prison/util/ExampleJavaDoubleVsBigDecimal.java | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/prison-core/src/main/java/tech/mcprison/prison/util/ExampleJavaDoubleVsBigDecimal.java b/prison-core/src/main/java/tech/mcprison/prison/util/ExampleJavaDoubleVsBigDecimal.java index ec35b5650..807cd35db 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/util/ExampleJavaDoubleVsBigDecimal.java +++ b/prison-core/src/main/java/tech/mcprison/prison/util/ExampleJavaDoubleVsBigDecimal.java @@ -13,11 +13,13 @@ public static void main( String[] args ) { ArrayList out = app.runSample(); String header = String.format( - "%s %45s %55s %35s %s", + "%s %45s %3s %55s %3s %35s %s", "Int Digits ", " double ", + "Row", " BigDecimal ", - "Delta ", + "Row", + "Delta - loss of double precision ", "Row" ); System.out.println( header ); @@ -34,7 +36,7 @@ private ArrayList runSample() { StringBuilder sb = new StringBuilder(); sb.append( ".111111" ); - DecimalFormat dFmt = new DecimalFormat( "#,##0.00000" ); + DecimalFormat dFmt = new DecimalFormat( "#,##0.000000" ); // DecimalFormat iFmt = new DecimalFormat( "#,##0.00000" ); for ( int i = 1; i < 35; i++ ) { @@ -46,10 +48,12 @@ private ArrayList runSample() { BigDecimal delta = bigD.subtract( BigDecimal.valueOf(dub) ); String rpt = String.format( - "%3d %55s %55s %35s %3d", + "%3d %55s %3d %55s %3d %35s %3d", i, dFmt.format( dub ), + i, dFmt.format( bigD ), + i, dFmt.format( delta ), i ); From fb5c28a4910771dad41eb5f6217634d6618ca74c Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Fri, 22 Sep 2023 00:52:09 -0400 Subject: [PATCH 115/151] Prison compatibility: Added support for block metadata customModelData. This is only compatible with spigot 1.14.x and higher. --- docs/changelog_v3.3.x.md | 4 + .../spigot/compat/CompatibilityBlocks.java | 33 ++++++ .../spigot/compat/SpigotCompatibility.java | 14 ++- .../{Spigot113.java => Spigot_1_13.java} | 4 +- ...113Blocks.java => Spigot_1_13_Blocks.java} | 4 +- ...Spigot113GUI.java => Spigot_1_13_GUI.java} | 4 +- .../prison/spigot/compat/Spigot_1_14.java | 6 + .../spigot/compat/Spigot_1_14_Blocks.java | 109 ++++++++++++++++++ .../{Spigot118.java => Spigot_1_18.java} | 5 +- .../compat/{Spigot18.java => Spigot_1_8.java} | 4 +- ...ot18Blocks.java => Spigot_1_8_Blocks.java} | 51 +++++++- .../{Spigot18GUI.java => Spigot_1_8_GUI.java} | 4 +- ...ot18Player.java => Spigot_1_8_Player.java} | 2 +- .../compat/{Spigot19.java => Spigot_1_9.java} | 4 +- .../{Spigot19GUI.java => Spigot_1_9_GUI.java} | 4 +- ...ot19Player.java => Spigot_1_9_Player.java} | 4 +- 16 files changed, 230 insertions(+), 26 deletions(-) rename prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/{Spigot113.java => Spigot_1_13.java} (98%) rename prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/{Spigot113Blocks.java => Spigot_1_13_Blocks.java} (99%) rename prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/{Spigot113GUI.java => Spigot_1_13_GUI.java} (77%) create mode 100644 prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot_1_14.java create mode 100644 prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot_1_14_Blocks.java rename prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/{Spigot118.java => Spigot_1_18.java} (72%) rename prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/{Spigot18.java => Spigot_1_8.java} (98%) rename prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/{Spigot18Blocks.java => Spigot_1_8_Blocks.java} (94%) rename prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/{Spigot18GUI.java => Spigot_1_8_GUI.java} (80%) rename prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/{Spigot18Player.java => Spigot_1_8_Player.java} (98%) rename prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/{Spigot19.java => Spigot_1_9.java} (98%) rename prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/{Spigot19GUI.java => Spigot_1_9_GUI.java} (80%) rename prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/{Spigot19Player.java => Spigot_1_9_Player.java} (96%) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 3939a32f6..e8a9b5df2 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -17,6 +17,10 @@ These change logs represent the work that has been going on within prison. # 3.3.0-alpha.15e 2023-09-21 +* **Prison compatibility: Added support for block metadata customModelData.** +This is only compatible with spigot 1.14.x and higher. + + * **Ranks Ladder resetRankCost: Added a new parameter to provide an exponent which is used as a Math.pow() function over the base rank cost calculations.** This can help increase the rank costs for higher ranks. Default value is 1.0 so it does not apply unless it is specifically changed. diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/CompatibilityBlocks.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/CompatibilityBlocks.java index dc3bc50ad..8b1be84a3 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/CompatibilityBlocks.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/CompatibilityBlocks.java @@ -70,4 +70,37 @@ public interface CompatibilityBlocks public int getMaxY(); + + + /** + * Not compatible with Spigot 1.8 through 1.13 so return a value of 0. + * Only available with 1.14 and higher. + * @param itemStack + * @return + */ + public int getCustomModelData( SpigotItemStack itemStack ); + /** + * Not compatible with Spigot 1.8 through 1.13 so return a value of 0. + * Only available with 1.14 and higher. + * @param itemStack + * @return + */ + public int getCustomModelData( ItemStack itemStack ); + + /** + * Not compatible with Spigot 1.8 through 1.13 so do nothing. + * Only available with 1.14 and higher. + * @param itemStack + * @return + */ + public void setCustomModelData( SpigotItemStack itemStack, int customModelData ); + /** + * Not compatible with Spigot 1.8 through 1.13 so do nothing. + * Only available with 1.14 and higher. + * @param itemStack + * @return + */ + public void setCustomModelData( ItemStack itemStack, int customModelData ); + + } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/SpigotCompatibility.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/SpigotCompatibility.java index 6199c23c5..ce98af5fa 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/SpigotCompatibility.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/SpigotCompatibility.java @@ -27,7 +27,7 @@ private static synchronized void setup() { if ( bukkitVersion == null ) { - results = new Spigot113(); + results = new Spigot_1_13(); } else { @@ -35,19 +35,23 @@ private static synchronized void setup() { if ( svData.compareTo( new BluesSemanticVersionData( "1.9.0" ) ) < 0 ) { - results = new Spigot18(); + results = new Spigot_1_8(); } else if ( svData.compareTo( new BluesSemanticVersionData( "1.13.0" ) ) < 0 ) { - results = new Spigot19(); + results = new Spigot_1_9(); + } + else if ( svData.compareTo( new BluesSemanticVersionData( "1.14.0" ) ) < 0 ) { + + results = new Spigot_1_13(); } else if ( svData.compareTo( new BluesSemanticVersionData( "1.18.0" ) ) < 0 ) { - results = new Spigot113(); + results = new Spigot_1_14(); } else { - results = new Spigot118(); + results = new Spigot_1_18(); } } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot113.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot_1_13.java similarity index 98% rename from prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot113.java rename to prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot_1_13.java index e0d296255..86c3642a8 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot113.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot_1_13.java @@ -12,8 +12,8 @@ import tech.mcprison.prison.spigot.block.SpigotItemStack; import tech.mcprison.prison.spigot.inventory.SpigotPlayerInventory; -public class Spigot113 - extends Spigot113GUI +public class Spigot_1_13 + extends Spigot_1_13_GUI implements Compatibility { @Override diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot113Blocks.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot_1_13_Blocks.java similarity index 99% rename from prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot113Blocks.java rename to prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot_1_13_Blocks.java index b27af2194..f0d86452b 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot113Blocks.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot_1_13_Blocks.java @@ -19,8 +19,8 @@ import tech.mcprison.prison.spigot.block.SpigotItemStack; import tech.mcprison.prison.util.Location; -public abstract class Spigot113Blocks - extends Spigot19Player +public abstract class Spigot_1_13_Blocks + extends Spigot_1_9_Player implements CompatibilityBlocks { // @Override diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot113GUI.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot_1_13_GUI.java similarity index 77% rename from prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot113GUI.java rename to prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot_1_13_GUI.java index 62acc09b9..94ad8c1c4 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot113GUI.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot_1_13_GUI.java @@ -2,8 +2,8 @@ import org.bukkit.event.inventory.InventoryEvent; -public abstract class Spigot113GUI - extends Spigot113Blocks +public abstract class Spigot_1_13_GUI + extends Spigot_1_13_Blocks implements CompatibilityGUI { @Override diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot_1_14.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot_1_14.java new file mode 100644 index 000000000..754779bd1 --- /dev/null +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot_1_14.java @@ -0,0 +1,6 @@ +package tech.mcprison.prison.spigot.compat; + +public class Spigot_1_14 + extends Spigot_1_14_Blocks { + +} diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot_1_14_Blocks.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot_1_14_Blocks.java new file mode 100644 index 000000000..9a76d4372 --- /dev/null +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot_1_14_Blocks.java @@ -0,0 +1,109 @@ +package tech.mcprison.prison.spigot.compat; + +import java.lang.reflect.Method; + +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +import tech.mcprison.prison.spigot.block.SpigotItemStack; + +public class Spigot_1_14_Blocks + extends Spigot_1_13 + //implements CompatibilityBlocks +{ + + private static Method SET_CUSTOM_MODEL_DATA = null; + private static Method GET_CUSTOM_MODEL_DATA = null; + + static { + try { + SET_CUSTOM_MODEL_DATA = ItemMeta.class.getDeclaredMethod("setCustomModelData", Integer.class); + GET_CUSTOM_MODEL_DATA = ItemMeta.class.getDeclaredMethod("getCustomModelData"); + } + catch (NoSuchMethodException ex) { + ex.printStackTrace(); + } + } + + /** + * Not compatible with Spigot 1.8 through 1.13 so return a value of 0. + * Only available with 1.14 and higher. + * @param itemStack + * @return + */ + @Override + public int getCustomModelData( SpigotItemStack itemStack ) { + return getCustomModelData( itemStack == null ? null : itemStack.getBukkitStack() ); + } + /** + * Not compatible with Spigot 1.8 through 1.13 so return a value of 0. + * Only available with 1.14 and higher. + * @param itemStack + * @return + */ + @Override + public int getCustomModelData( ItemStack itemStack ) { + int results = 0; + + if ( itemStack != null ) { + ItemMeta meta = itemStack.getItemMeta(); + + if (meta != null) { + try { + Integer customModelData = (Integer) GET_CUSTOM_MODEL_DATA.invoke(meta); + + if ( customModelData != null ) { + results = customModelData.intValue(); + } + } + catch (ReflectiveOperationException ex ) { + ex.printStackTrace(); + } + catch ( ClassCastException ex ) { + ex.printStackTrace(); + } + } + itemStack.setItemMeta(meta); + } + + return results; + } + + /** + * Not compatible with Spigot 1.8 through 1.13 so do nothing. + * Only available with 1.14 and higher. + * @param itemStack + * @return + */ + @Override + public void setCustomModelData( SpigotItemStack itemStack, int customModelData ) { + if ( itemStack != null ) { + setCustomModelData( itemStack.getBukkitStack(), customModelData); + } + } + /** + * Not compatible with Spigot 1.8 through 1.13 so do nothing. + * Only available with 1.14 and higher. + * @param itemStack + * @return + */ + @Override + public void setCustomModelData( ItemStack itemStack, int customModelData ) { + + if ( itemStack != null ) { + ItemMeta meta = itemStack.getItemMeta(); + + if (meta != null) { + try { + + SET_CUSTOM_MODEL_DATA.invoke( meta, customModelData ); + } + catch (ReflectiveOperationException ex) { + ex.printStackTrace(); + } + } + itemStack.setItemMeta(meta); + } + + } +} diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot118.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot_1_18.java similarity index 72% rename from prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot118.java rename to prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot_1_18.java index f4ef76aab..2ef9cb96b 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot118.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot_1_18.java @@ -1,7 +1,8 @@ package tech.mcprison.prison.spigot.compat; -public class Spigot118 - extends Spigot113 +public class Spigot_1_18 + extends Spigot_1_14 + implements Compatibility { diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot18.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot_1_8.java similarity index 98% rename from prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot18.java rename to prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot_1_8.java index 2c0f89864..ec7cffb74 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot18.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot_1_8.java @@ -33,8 +33,8 @@ /** * @author Faizaan A. Datoo */ -public class Spigot18 - extends Spigot18GUI +public class Spigot_1_8 + extends Spigot_1_8_GUI implements Compatibility { diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot18Blocks.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot_1_8_Blocks.java similarity index 94% rename from prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot18Blocks.java rename to prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot_1_8_Blocks.java index 2220155fe..fbb1b65c6 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot18Blocks.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot_1_8_Blocks.java @@ -15,8 +15,8 @@ import tech.mcprison.prison.spigot.block.SpigotItemStack; import tech.mcprison.prison.util.Location; -public abstract class Spigot18Blocks - extends Spigot18Player +public abstract class Spigot_1_8_Blocks + extends Spigot_1_8_Player implements CompatibilityBlocks { @@ -753,4 +753,51 @@ public int getMaxY() { return 255; } + + /** + * Not compatible with Spigot 1.8 through 1.13 so return a value of 0. + * Only available with 1.14 and higher. + * @param itemStack + * @return + */ + @Override + public int getCustomModelData( SpigotItemStack itemStack ) { + return 0; + } + /** + * Not compatible with Spigot 1.8 through 1.13 so return a value of 0. + * Only available with 1.14 and higher. + * @param itemStack + * @return + */ + @Override + public int getCustomModelData( ItemStack itemStack ) { + return 0; + } + + /** + * Not compatible with Spigot 1.8 through 1.13 so do nothing. + * Only available with 1.14 and higher. + * @param itemStack + * @return + */ + @Override + public void setCustomModelData( SpigotItemStack itemStack, int customModelData ) { + if ( itemStack != null ) { + setCustomModelData( itemStack.getBukkitStack(), customModelData); + } + } + /** + * Not compatible with Spigot 1.8 through 1.13 so do nothing. + * Only available with 1.14 and higher. + * @param itemStack + * @return + */ + @Override + public void setCustomModelData( ItemStack itemStack, int customModelData ) { + + } + + + } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot18GUI.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot_1_8_GUI.java similarity index 80% rename from prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot18GUI.java rename to prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot_1_8_GUI.java index 7a30037c2..a7a288b31 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot18GUI.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot_1_8_GUI.java @@ -2,8 +2,8 @@ import org.bukkit.event.inventory.InventoryEvent; -public abstract class Spigot18GUI - extends Spigot18Blocks +public abstract class Spigot_1_8_GUI + extends Spigot_1_8_Blocks implements CompatibilityGUI { @SuppressWarnings( "deprecation" ) diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot18Player.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot_1_8_Player.java similarity index 98% rename from prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot18Player.java rename to prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot_1_8_Player.java index 32de7241f..4e35f8fb6 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot18Player.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot_1_8_Player.java @@ -7,7 +7,7 @@ import tech.mcprison.prison.util.Text; -public abstract class Spigot18Player +public abstract class Spigot_1_8_Player extends CompatibilityCache implements CompatibilityPlayer { diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot19.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot_1_9.java similarity index 98% rename from prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot19.java rename to prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot_1_9.java index 5b3a2e2d5..b6fb32c73 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot19.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot_1_9.java @@ -35,8 +35,8 @@ * * @author Faizaan A. Datoo */ -public class Spigot19 - extends Spigot19GUI +public class Spigot_1_9 + extends Spigot_1_9_GUI implements Compatibility { @Override diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot19GUI.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot_1_9_GUI.java similarity index 80% rename from prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot19GUI.java rename to prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot_1_9_GUI.java index 3268e52ad..92402b13f 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot19GUI.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot_1_9_GUI.java @@ -2,8 +2,8 @@ import org.bukkit.event.inventory.InventoryEvent; -public class Spigot19GUI - extends Spigot19Player +public class Spigot_1_9_GUI + extends Spigot_1_9_Player implements CompatibilityGUI { @Override diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot19Player.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot_1_9_Player.java similarity index 96% rename from prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot19Player.java rename to prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot_1_9_Player.java index 370aa8045..ce90aca41 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot19Player.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot_1_9_Player.java @@ -9,8 +9,8 @@ import tech.mcprison.prison.util.Text; -public abstract class Spigot19Player - extends Spigot18Blocks +public abstract class Spigot_1_9_Player + extends Spigot_1_8_Blocks { public void setMaxHealth( Player player, double maxHealth ) { From f04be331b4e34ff707543489d4e51236bdf8ab1b Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Fri, 22 Sep 2023 00:58:44 -0400 Subject: [PATCH 116/151] MineBombs: Add support for customModelData for the item used for the bomb. This will only work on spigot version 1.14.x and higher. --- docs/changelog_v3.3.x.md | 4 ++++ .../tech/mcprison/prison/bombs/MineBombData.java | 16 ++++++++++++++++ .../tech/mcprison/prison/bombs/MineBombs.java | 3 +++ .../prison/bombs/MineBombsConfigData.java | 2 +- .../spigot/utils/PrisonUtilsMineBombs.java | 6 ++++++ 5 files changed, 30 insertions(+), 1 deletion(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index e8a9b5df2..0d4c5467a 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -17,6 +17,10 @@ These change logs represent the work that has been going on within prison. # 3.3.0-alpha.15e 2023-09-21 +* **MineBombs: Add support for customModelData for the item used for the bomb.** +This will only work on spigot version 1.14.x and higher. + + * **Prison compatibility: Added support for block metadata customModelData.** This is only compatible with spigot 1.14.x and higher. diff --git a/prison-core/src/main/java/tech/mcprison/prison/bombs/MineBombData.java b/prison-core/src/main/java/tech/mcprison/prison/bombs/MineBombData.java index d341e3b8c..9f2744a9d 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/bombs/MineBombData.java +++ b/prison-core/src/main/java/tech/mcprison/prison/bombs/MineBombData.java @@ -179,6 +179,10 @@ public class MineBombData { private boolean autosell = false; + + private int customModelData = 0; + + /** *

This is a list of mine names where a mine bomb is allowed to be used. * This setting overrides any global setting to disallow a specific mine, which @@ -267,6 +271,9 @@ public MineBombData( String name, String itemType, String explosionShape, this.glowing = false; this.gravity = true; + this.autosell = false; + this.customModelData = 0; + } @@ -304,6 +311,8 @@ public MineBombData clone() { cloned.setAutosell( isAutosell() ); cloned.setActivated( isActivated() ); + cloned.setCustomModelData( getCustomModelData() ); + for ( String l : getLore() ) { cloned.getLore().add( l ); @@ -504,6 +513,13 @@ public void setAutosell( boolean autosell ) { this.autosell = autosell; } + public int getCustomModelData() { + return customModelData; + } + public void setCustomModelData(int customModelData) { + this.customModelData = customModelData; + } + public List getAllowedMines() { return allowedMines; } diff --git a/prison-core/src/main/java/tech/mcprison/prison/bombs/MineBombs.java b/prison-core/src/main/java/tech/mcprison/prison/bombs/MineBombs.java index eb22b99c9..0a1c2e592 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/bombs/MineBombs.java +++ b/prison-core/src/main/java/tech/mcprison/prison/bombs/MineBombs.java @@ -129,6 +129,9 @@ public void saveConfigJson() { File configFile = getConfigFile( fio ); + // Ensure it's set to the correct data version so it won't falsely resave on reload: + getConfigData().setDataFormatVersion( MineBombsConfigData.MINE_BOMB_DATA_FORMAT_VERSION ); + fio.saveJsonFile( configFile, getConfigData() ); } diff --git a/prison-core/src/main/java/tech/mcprison/prison/bombs/MineBombsConfigData.java b/prison-core/src/main/java/tech/mcprison/prison/bombs/MineBombsConfigData.java index 4c34d0b99..14861671c 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/bombs/MineBombsConfigData.java +++ b/prison-core/src/main/java/tech/mcprison/prison/bombs/MineBombsConfigData.java @@ -18,7 +18,7 @@ public class MineBombsConfigData */ public static final int MINE_BOMB_DATA_FORMAT_VERSION = 2; - private int dataFormatVersion = 1; + private int dataFormatVersion = 0; private Map bombs; diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/PrisonUtilsMineBombs.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/PrisonUtilsMineBombs.java index b57eb1124..56c26c6d5 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/PrisonUtilsMineBombs.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/PrisonUtilsMineBombs.java @@ -698,6 +698,7 @@ public static ItemStack getItemStackBomb( MineBombData bombData ) { bombs.setLore( lore ); + // SpigotCompatibility.getInstance().setCustomModelData( bombs, bombData.getCustomModelData() ); sItemStack = bombs.getBukkitStack(); } @@ -709,6 +710,11 @@ public static ItemStack getItemStackBomb( MineBombData bombData ) { // nbtItem = new NBTItem( sItemStack, true ); // nbtItem.setString( MineBombs.MINE_BOMBS_NBT_BOMB_KEY, bombData.getName() ); + + // Set the customModelData on the bomb to allow for custom skins: + SpigotCompatibility.getInstance().setCustomModelData( sItemStack, bombData.getCustomModelData() ); + + if ( Output.get().isDebug() ) { Output.get().logInfo( "getItemStackBombs ntb: %s", PrisonNBTUtil.nbtDebugString(sItemStack) ); } From 9909d921c19db6aa28a024e59f9b334a26fa5fee Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Fri, 22 Sep 2023 02:10:57 -0400 Subject: [PATCH 117/151] MineBombs: validate all mine bombs upon server startup to validate the sound effects, visual effects, and shape based upon the version of spigot that they are running. This mostly is to clean up the default mine bombs where they have sound and visual effects for versions of spigot so something will happen. This removes the invalid ones for the version so there are less errors at run time. --- docs/changelog_v3.3.x.md | 6 +- .../mcprison/prison/spigot/SpigotPrison.java | 4 +- .../spigot/utils/PrisonUtilsMineBombs.java | 147 ++++++++++++++++++ 3 files changed, 154 insertions(+), 3 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 0d4c5467a..4e6951da8 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -14,7 +14,11 @@ These change logs represent the work that has been going on within prison. -# 3.3.0-alpha.15e 2023-09-21 +# 3.3.0-alpha.15e 2023-09-22 + + +* **MineBombs: validate all mine bombs upon server startup to validate the sound effects, visual effects, and shape based upon the version of spigot that they are running.** +This mostly is to clean up the default mine bombs where they have sound and visual effects for versions of spigot so something will happen. This removes the invalid ones for the version so there are less errors at run time. * **MineBombs: Add support for customModelData for the item used for the bomb.** diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/SpigotPrison.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/SpigotPrison.java index bcb8c58f0..cecaf3cf5 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/SpigotPrison.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/SpigotPrison.java @@ -418,9 +418,9 @@ public void onEnableStartup() { - // Setup mine bombs: + // Setup mine bombs and validate to spigot version: PrisonUtilsMineBombs.getInstance().reloadPrisonMineBombs(); - + PrisonUtilsMineBombs.getInstance().validateMineBombsSpigotVersion(); // Enable Temp spigot commands: new SpigotCommand(); diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/PrisonUtilsMineBombs.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/PrisonUtilsMineBombs.java index 56c26c6d5..d66e85304 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/PrisonUtilsMineBombs.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/PrisonUtilsMineBombs.java @@ -3,6 +3,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.Map; import java.util.Set; import org.bukkit.Bukkit; @@ -88,6 +89,8 @@ public static PrisonUtilsMineBombs getInstance() { @Override protected Boolean initialize() { + //validateMineBombs(); + return true; } @@ -457,6 +460,7 @@ public void utilsMineBombsList( CommandSender sender, } } + @Command(identifier = "prison utils bomb give", description = "Gives the player a mine bomb. Can also provide a list of " + @@ -1022,6 +1026,149 @@ else if ( bomb != null ) { } + public boolean validateMineBombsSpigotVersion() { + boolean results = true; + + MineBombs mBombs = MineBombs.getInstance(); + + Map bombs = mBombs.getConfigData().getBombs(); + + Set keys = bombs.keySet(); + for ( String key : keys ) { + MineBombData mbData = bombs.get( key ); + + List deleteSounds = new ArrayList<>(); + for ( MineBombEffectsData sEffect : mbData.getSoundEffects() ) { + + if ( !utilsMineBombsValidate( "sounds", sEffect.getEffectName() ) ) { + results = false; + deleteSounds.add( sEffect ); + + Output.get().logInfo( "MineBomb Validation Error: Invalid sound removed: %s : [%s]", + mbData.getName(), sEffect.toString() ); + } + } + if ( deleteSounds.size() > 0 ) { + mbData.getSoundEffects().removeAll( deleteSounds ); + } + + List deleteVisuals = new ArrayList<>(); + for ( MineBombEffectsData sEffect : mbData.getVisualEffects() ) { + + if ( !utilsMineBombsValidate( "visuals", sEffect.getEffectName() ) ) { + results = false; + deleteVisuals.add( sEffect ); + + Output.get().logInfo( "MineBomb Validation Error: Invalid visual removed: %s : [%s]", + mbData.getName(), sEffect.toStringShort() ); + } + } + if ( deleteVisuals.size() > 0 ) { + mbData.getVisualEffects().removeAll( deleteSounds ); + } + + if ( !utilsMineBombsValidate( "shapes", mbData.getExplosionShape() ) ) { + results = false; + + Output.get().logInfo( "MineBomb Validation Error: Invalid shape changed to 'sphere': %s : [%s]", + mbData.getName(), mbData.getExplosionShape() ); + + mbData.setExplosionShape( ExplosionShape.sphere.name() ); + + } + + + } + + if ( !results ) { + // There was an invalid setting. Save the changed configs: + Output.get().logInfo( "MineBomb Validation: Saving mine bombs due to changes in the configs." ); + + mBombs.saveConfigJson(); + } + + return results; + } + + + public boolean utilsMineBombsValidate( String mbObjectType, + String name + ) { + + boolean results = false; + + if ( mbObjectType == null ) { + Output.get().logInfo( "Prison util MineBomb: utilsMineBombsValidate: Error: objectType is null" ); + } + else if ( name == null ) { + Output.get().logInfo( "Prison util MineBomb: utilsMineBombsValidate: Error: name is null" ); + } + + else if ( !isEnableMineBombs() ) { + + Output.get().logInfo( "Prison's utils command mine bombs is disabled in modules.yml." ); + } + else { + + + if ( mbObjectType.equalsIgnoreCase( "shapes" ) ) { + + List shapes = ExplosionShape.asList(); + for (String shape : shapes) { + if ( shape.equalsIgnoreCase( name ) ) { + results = true; + break; + } + } + + } + + else if ( mbObjectType.equalsIgnoreCase( "sounds" ) ) { + + + for ( XSound p : XSound.values() ) { + if ( p.name().equalsIgnoreCase( name ) ) { + results = true; + break; + } + } + + } + + else if ( mbObjectType.equalsIgnoreCase( "visuals" ) ) { + + // bukkit 1.8.8: +// Effect.values() + + // If running less than MC 1.9.0, ie 1.8.x, then use different code for effects: + boolean is1_8 = new BluesSpigetSemVerComparator().compareMCVersionTo( "1.9.0" ) < 0 ; + + if ( is1_8 ) { + for ( Effect p : Effect.values() ) { + if ( p.name().equalsIgnoreCase( name ) ) { + results = true; + break; + } + } + + } + else { + + for ( Particle p : Particle.values() ) { + if ( p.name().equalsIgnoreCase( name ) ) { + results = true; + break; + } + } + } + } + + } + + return results; + } + + // public void placeMineBombItem( MineBombData bomb, SpigotBlock sBlock, SpigotItemStack item ) { // From 4acd2684920c497fe432077acb9ab378cd89ab69 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Fri, 22 Sep 2023 04:06:38 -0400 Subject: [PATCH 118/151] v3.3.0-alpha.15f 2023-09-22 --- docs/changelog_v3.3.x.md | 6 +++++- gradle.properties | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 4e6951da8..4dc0238eb 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -14,7 +14,11 @@ These change logs represent the work that has been going on within prison. -# 3.3.0-alpha.15e 2023-09-22 +# 3.3.0-alpha.15f 2023-09-22 + + + +**v3.3.0-alpha.15f 2023-09-22** * **MineBombs: validate all mine bombs upon server startup to validate the sound effects, visual effects, and shape based upon the version of spigot that they are running.** diff --git a/gradle.properties b/gradle.properties index e053cfe59..f5304a428 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,7 +3,7 @@ ## # This is actually the "correct" place to define the version for the project. ## # Used within build.gradle with ${project.version}. ## # Can be overridden on the command line: gradle -Pversion=3.2.1-alpha.3 -version=3.3.0-alpha.15e +version=3.3.0-alpha.15f From a6ef0e92f0e28014931fc92d9797dec1acb47057 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 23 Sep 2023 22:03:53 -0400 Subject: [PATCH 119/151] Changed the default color code from `&9` (dark blue) to `&b` (light blue) for debug logging since the dark blue could be difficult to see on some consoles. --- docs/changelog_v3.3.x.md | 2 ++ prison-core/src/main/resources/lang/core/de_DE.properties | 2 +- prison-core/src/main/resources/lang/core/en_GB.properties | 2 +- prison-core/src/main/resources/lang/core/en_US.properties | 2 +- prison-core/src/main/resources/lang/core/es_ES.properties | 2 +- prison-core/src/main/resources/lang/core/fi_FI.properties | 2 +- prison-core/src/main/resources/lang/core/fr_FR.properties | 2 +- prison-core/src/main/resources/lang/core/hu_HU.properties | 2 +- prison-core/src/main/resources/lang/core/it_IT.properties | 2 +- prison-core/src/main/resources/lang/core/nl_BE.properties | 2 +- prison-core/src/main/resources/lang/core/nl_NL.properties | 2 +- prison-core/src/main/resources/lang/core/pt_PT.properties | 2 +- prison-core/src/main/resources/lang/core/ro_RO.properties | 2 +- prison-core/src/main/resources/lang/core/zh-CN.properties | 2 +- prison-core/src/main/resources/lang/core/zh_TW.properties | 2 +- 15 files changed, 16 insertions(+), 14 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 4dc0238eb..688e7d836 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -17,6 +17,8 @@ These change logs represent the work that has been going on within prison. # 3.3.0-alpha.15f 2023-09-22 +* **Changed the default color code from `&9` (dark blue) to `&b` (light blue) for debug logging since the dark blue could be difficult to see on some consoles. + **v3.3.0-alpha.15f 2023-09-22** diff --git a/prison-core/src/main/resources/lang/core/de_DE.properties b/prison-core/src/main/resources/lang/core/de_DE.properties index 572803be6..e426fcec9 100644 --- a/prison-core/src/main/resources/lang/core/de_DE.properties +++ b/prison-core/src/main/resources/lang/core/de_DE.properties @@ -93,7 +93,7 @@ core_output__prefix_template_debug=Debug core_output__color_code_info=&3 core_output__color_code_warning=&c core_output__color_code_error=&c -core_output__color_code_debug=&9 +core_output__color_code_debug=&b core_output__error_startup_failure=Prison: (Sending to System.err due to Output.log Logger failure): core_output__error_incorrect_number_of_parameters=Log Failure (%1): Incorrect number of parameters: [%2] Original raw message: [%3] Arguments: %4 diff --git a/prison-core/src/main/resources/lang/core/en_GB.properties b/prison-core/src/main/resources/lang/core/en_GB.properties index b9bed0f09..12a920078 100644 --- a/prison-core/src/main/resources/lang/core/en_GB.properties +++ b/prison-core/src/main/resources/lang/core/en_GB.properties @@ -90,7 +90,7 @@ core_output__prefix_template_debug=Debug core_output__color_code_info=&3 core_output__color_code_warning=&c core_output__color_code_error=&c -core_output__color_code_debug=&9 +core_output__color_code_debug=&b core_output__error_startup_failure=Prison: (Sending to System.err due to Output.log Logger failure): core_output__error_incorrect_number_of_parameters=Log Failure (%1): Incorrect number of parameters: [%2] Original raw message: [%3] Arguments: %4 diff --git a/prison-core/src/main/resources/lang/core/en_US.properties b/prison-core/src/main/resources/lang/core/en_US.properties index c433981d7..c5499c0d2 100644 --- a/prison-core/src/main/resources/lang/core/en_US.properties +++ b/prison-core/src/main/resources/lang/core/en_US.properties @@ -90,7 +90,7 @@ core_output__prefix_template_debug=Debug core_output__color_code_info=&3 core_output__color_code_warning=&c core_output__color_code_error=&c -core_output__color_code_debug=&9 +core_output__color_code_debug=&b core_output__error_startup_failure=Prison: (Sending to System.err due to Output.log Logger failure): core_output__error_incorrect_number_of_parameters=Log Failure (%1): Incorrect number of parameters: [%2] Original raw message: [%3] Arguments: %4 diff --git a/prison-core/src/main/resources/lang/core/es_ES.properties b/prison-core/src/main/resources/lang/core/es_ES.properties index 48c2aaebc..b6e6fbcde 100644 --- a/prison-core/src/main/resources/lang/core/es_ES.properties +++ b/prison-core/src/main/resources/lang/core/es_ES.properties @@ -90,7 +90,7 @@ core_output__prefix_template_debug=Debug core_output__color_code_info=&3 core_output__color_code_warning=&c core_output__color_code_error=&c -core_output__color_code_debug=&9 +core_output__color_code_debug=&b core_output__error_startup_failure=Prison: (Sending to System.err due to Output.log Logger failure): core_output__error_incorrect_number_of_parameters=Log Failure (%1): Incorrect number of parameters: [%2] Original raw message: [%3] Arguments: %4 diff --git a/prison-core/src/main/resources/lang/core/fi_FI.properties b/prison-core/src/main/resources/lang/core/fi_FI.properties index d7dcd6e37..831d6af77 100644 --- a/prison-core/src/main/resources/lang/core/fi_FI.properties +++ b/prison-core/src/main/resources/lang/core/fi_FI.properties @@ -90,7 +90,7 @@ core_output__prefix_template_debug=Debug core_output__color_code_info=&3 core_output__color_code_warning=&c core_output__color_code_error=&c -core_output__color_code_debug=&9 +core_output__color_code_debug=&b core_output__error_startup_failure=Prison: (Sending to System.err due to Output.log Logger failure): core_output__error_incorrect_number_of_parameters=Log Failure (%1): Incorrect number of parameters: [%2] Original raw message: [%3] Arguments: %4 diff --git a/prison-core/src/main/resources/lang/core/fr_FR.properties b/prison-core/src/main/resources/lang/core/fr_FR.properties index ad4ac402b..9997d0444 100644 --- a/prison-core/src/main/resources/lang/core/fr_FR.properties +++ b/prison-core/src/main/resources/lang/core/fr_FR.properties @@ -90,7 +90,7 @@ core_output__prefix_template_debug=Debug core_output__color_code_info=&3 core_output__color_code_warning=&c core_output__color_code_error=&c -core_output__color_code_debug=&9 +core_output__color_code_debug=&b core_output__error_startup_failure=Prison: (Envoi à System.err en raison de l'échec du log d'Output.log): core_output__error_incorrect_number_of_parameters=Échec du log (%1): Nombre de paramètres incorrect: [%2] Message brut original: [%3] Arguments: %4 diff --git a/prison-core/src/main/resources/lang/core/hu_HU.properties b/prison-core/src/main/resources/lang/core/hu_HU.properties index 8c8534d30..fee17ae76 100644 --- a/prison-core/src/main/resources/lang/core/hu_HU.properties +++ b/prison-core/src/main/resources/lang/core/hu_HU.properties @@ -90,7 +90,7 @@ core_output__prefix_template_debug=Debug core_output__color_code_info=&3 core_output__color_code_warning=&c core_output__color_code_error=&c -core_output__color_code_debug=&9 +core_output__color_code_debug=&b core_output__error_startup_failure=Prison: (Sending to System.err due to Output.log Logger failure): core_output__error_incorrect_number_of_parameters=Log Failure (%1): Incorrect number of parameters: [%2] Original raw message: [%3] Arguments: %4 diff --git a/prison-core/src/main/resources/lang/core/it_IT.properties b/prison-core/src/main/resources/lang/core/it_IT.properties index 28485c49b..7868eee2f 100644 --- a/prison-core/src/main/resources/lang/core/it_IT.properties +++ b/prison-core/src/main/resources/lang/core/it_IT.properties @@ -90,7 +90,7 @@ core_output__prefix_template_debug=Debug core_output__color_code_info=&3 core_output__color_code_warning=&c core_output__color_code_error=&c -core_output__color_code_debug=&9 +core_output__color_code_debug=&b core_output__error_startup_failure=Prison: (Sending to System.err due to Output.log Logger failure): core_output__error_incorrect_number_of_parameters=Log Failure (%1): Incorrect number of parameters: [%2] Original raw message: [%3] Arguments: %4 diff --git a/prison-core/src/main/resources/lang/core/nl_BE.properties b/prison-core/src/main/resources/lang/core/nl_BE.properties index 729dbc373..bec93ed55 100644 --- a/prison-core/src/main/resources/lang/core/nl_BE.properties +++ b/prison-core/src/main/resources/lang/core/nl_BE.properties @@ -90,7 +90,7 @@ core_output__prefix_template_debug=Debug core_output__color_code_info=&3 core_output__color_code_warning=&c core_output__color_code_error=&c -core_output__color_code_debug=&9 +core_output__color_code_debug=&b core_output__error_startup_failure=Prison: (Sending to System.err due to Output.log Logger failure): core_output__error_incorrect_number_of_parameters=Log Failure (%1): Incorrect number of parameters: [%2] Original raw message: [%3] Arguments: %4 diff --git a/prison-core/src/main/resources/lang/core/nl_NL.properties b/prison-core/src/main/resources/lang/core/nl_NL.properties index a57dccea0..270b1fc24 100644 --- a/prison-core/src/main/resources/lang/core/nl_NL.properties +++ b/prison-core/src/main/resources/lang/core/nl_NL.properties @@ -90,7 +90,7 @@ core_output__prefix_template_debug=Debug core_output__color_code_info=&3 core_output__color_code_warning=&c core_output__color_code_error=&c -core_output__color_code_debug=&9 +core_output__color_code_debug=&b core_output__error_startup_failure=Prison: (Sending to System.err due to Output.log Logger failure): core_output__error_incorrect_number_of_parameters=Log Failure (%1): Incorrect number of parameters: [%2] Original raw message: [%3] Arguments: %4 diff --git a/prison-core/src/main/resources/lang/core/pt_PT.properties b/prison-core/src/main/resources/lang/core/pt_PT.properties index f2cac4109..9c87f5f9d 100644 --- a/prison-core/src/main/resources/lang/core/pt_PT.properties +++ b/prison-core/src/main/resources/lang/core/pt_PT.properties @@ -90,7 +90,7 @@ core_output__prefix_template_debug=Debug core_output__color_code_info=&3 core_output__color_code_warning=&c core_output__color_code_error=&c -core_output__color_code_debug=&9 +core_output__color_code_debug=&b core_output__error_startup_failure=Prison: (Sending to System.err due to Output.log Logger failure): core_output__error_incorrect_number_of_parameters=Log Failure (%1): Incorrect number of parameters: [%2] Original raw message: [%3] Arguments: %4 diff --git a/prison-core/src/main/resources/lang/core/ro_RO.properties b/prison-core/src/main/resources/lang/core/ro_RO.properties index 285e21b41..647284ad2 100644 --- a/prison-core/src/main/resources/lang/core/ro_RO.properties +++ b/prison-core/src/main/resources/lang/core/ro_RO.properties @@ -90,7 +90,7 @@ core_output__prefix_template_debug=Debug core_output__color_code_info=&3 core_output__color_code_warning=&c core_output__color_code_error=&c -core_output__color_code_debug=&9 +core_output__color_code_debug=&b core_output__error_startup_failure=Prison: (Sending to System.err due to Output.log Logger failure): core_output__error_incorrect_number_of_parameters=Log Failure (%1): Incorrect number of parameters: [%2] Original raw message: [%3] Arguments: %4 diff --git a/prison-core/src/main/resources/lang/core/zh-CN.properties b/prison-core/src/main/resources/lang/core/zh-CN.properties index c4bcb227d..cfeca845d 100644 --- a/prison-core/src/main/resources/lang/core/zh-CN.properties +++ b/prison-core/src/main/resources/lang/core/zh-CN.properties @@ -91,7 +91,7 @@ core_output__prefix_template_debug=Debug core_output__color_code_info=&3 core_output__color_code_warning=&c core_output__color_code_error=&c -core_output__color_code_debug=&9 +core_output__color_code_debug=&b core_output__error_startup_failure=监狱: (Sending to System.err due to Output.log Logger failure): core_output__error_incorrect_number_of_parameters= 日志失败(%1): Incorrect number of parameters: [%2] Original raw message: [%3] Arguments: %4 diff --git a/prison-core/src/main/resources/lang/core/zh_TW.properties b/prison-core/src/main/resources/lang/core/zh_TW.properties index 2f516ffc7..99880acb3 100644 --- a/prison-core/src/main/resources/lang/core/zh_TW.properties +++ b/prison-core/src/main/resources/lang/core/zh_TW.properties @@ -90,7 +90,7 @@ core_output__prefix_template_debug=Debug core_output__color_code_info=&3 core_output__color_code_warning=&c core_output__color_code_error=&c -core_output__color_code_debug=&9 +core_output__color_code_debug=&b core_output__error_startup_failure=Prison: (Sending to System.err due to Output.log Logger failure): core_output__error_incorrect_number_of_parameters=Log Failure (%1): Incorrect number of parameters: [%2] Original raw message: [%3] Arguments: %4 From c9fa8206059c434d07d881bdc542e143070a7e81 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 23 Sep 2023 22:16:02 -0400 Subject: [PATCH 120/151] Update some debug info on the block break event... trivial. --- .../autofeatures/events/AutoManagerBlockBreakEvents.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerBlockBreakEvents.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerBlockBreakEvents.java index e116f6d79..fa1dbf9df 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerBlockBreakEvents.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerBlockBreakEvents.java @@ -287,7 +287,7 @@ private void handleBlockBreakEvent( BlockBreakEvent e, BlockBreakPriority bbPrio StringBuilder debugInfo = new StringBuilder(); - debugInfo.append( String.format( "&9### ** handleBlockBreakEvent ** ### " + + debugInfo.append( String.format( "### ** handleBlockBreakEvent ** ### " + "(event: BlockBreakEvent, config: %s, priority: %s, canceled: %s) ", bbPriority.name(), bbPriority.getBukkitEventPriority().name(), @@ -506,7 +506,7 @@ else if ( cancelBy == EventListenerCancelBy.drops ) { if ( isBoolean( AutoFeatures.isForceSellAllOnInventoryWhenBukkitBlockBreakEventFires ) ) { pmEvent.getDebugInfo().append( Output.get().getColorCodeWarning()); - pmEvent.performSellAllOnPlayerInventoryLogged( "BlockBreakEvent sellall"); + pmEvent.performSellAllOnPlayerInventoryLogged( "FORCED BlockBreakEvent sellall"); pmEvent.getDebugInfo().append( Output.get().getColorCodeDebug()); } From 41a9cbaaa75d4c93b7808b1516d152cd740b6de2 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 23 Sep 2023 22:18:50 -0400 Subject: [PATCH 121/151] Auto features: change a few of the new line breaks so there are fewer. --- docs/changelog_v3.3.x.md | 3 +++ .../autofeatures/AutoManagerFeatures.java | 22 +++++++++---------- .../spigot/block/OnBlockBreakEventCore.java | 6 ++--- .../spigot/block/OnBlockBreakMines.java | 2 +- 4 files changed, 18 insertions(+), 15 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 688e7d836..4424e4fe2 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -17,6 +17,9 @@ These change logs represent the work that has been going on within prison. # 3.3.0-alpha.15f 2023-09-22 +* **Auto features: change a few of the new line breaks so there are fewer.** + + * **Changed the default color code from `&9` (dark blue) to `&b` (light blue) for debug logging since the dark blue could be difficult to see on some consoles. diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerFeatures.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerFeatures.java index 56e8db5ee..cba4abe45 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerFeatures.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerFeatures.java @@ -160,7 +160,7 @@ protected void printDebugInfo( PrisonMinesBlockBreakEvent pmEvent, double start if ( pmEvent != null && pmEvent.getDebugInfo().length() > 0 ) { long stop = System.nanoTime(); - pmEvent.getDebugInfo().append( "{br}### ** End Event Debug Info ** ### [" ) + pmEvent.getDebugInfo().append( "{br}|| ### ** End Event Debug Info ** ### [" ) .append( (stop - start) / 1000000d ) .append( " ms]" ); @@ -548,7 +548,7 @@ private int applyAutoEventsDetails( PrisonMinesBlockBreakEvent pmEvent ) { if ( Output.get().isDebug( DebugTarget.blockBreak ) ) { - pmEvent.getDebugInfo().append( "{br} (applyAutoEvents: " ) + pmEvent.getDebugInfo().append( "{br}|| (applyAutoEvents: " ) .append( pmEvent.getSpigotBlock().getBlockName() ); if ( !isAutoFeaturesEnabled ) { @@ -612,7 +612,7 @@ private int applyAutoEventsDetails( PrisonMinesBlockBreakEvent pmEvent ) { if ( configNormalDrop ) { pmEvent.getDebugInfo() - .append( "{br} (NormalDrop handling enabled: " ) + .append( "{br}|| (NormalDrop handling enabled: " ) .append( "normalDropSmelt[" ) .append( configNormalDropSmelt ? "enabled" : "disabled" ) .append( "] " ) @@ -813,7 +813,7 @@ protected int autoPickup( PrisonMinesBlockBreakEvent pmEvent, sb.insert( 0, "bukkitDropMult=" ); } - debugInfo.append( "{br} [autoPickupDrops:beforeFortune:: " ).append( sb ).append( "] "); + debugInfo.append( " [autoPickupDrops:beforeFortune:: " ).append( sb ).append( "] "); @@ -845,7 +845,7 @@ protected int autoPickup( PrisonMinesBlockBreakEvent pmEvent, .append( ":" ) .append( itemStack.getAmount() ); } - debugInfo.append( "{br} [totalDrops:afterFortune:: " ).append( sb ).append( "] "); + debugInfo.append( " [totalDrops:afterFortune:: " ).append( sb ).append( "] "); } @@ -1002,7 +1002,7 @@ protected int autoPickup( PrisonMinesBlockBreakEvent pmEvent, double amount = SellAllUtil.get().getItemStackValue( pmEvent.getSpigotPlayer(), itemStack ); autosellTotal += amount; - debugInfo.append( "{br} (WARNING: autosell leftovers: " + itemStack.getName() + + debugInfo.append( "{br}|| (WARNING: autosell leftovers: " + itemStack.getName() + " qty: " + itemStack.getAmount() + " value: " + dFmt.format( amount ) + " - " + ( amount == 0 ? " Items NOT in sellall shop!" : " CouldNotSell?") + @@ -1016,7 +1016,7 @@ protected int autoPickup( PrisonMinesBlockBreakEvent pmEvent, double amount = SellAllUtil.get().getItemStackValue( pmEvent.getSpigotPlayer(), itemStack ); autosellTotal += amount; - debugInfo.append( "{br} (Debug-unsold-value-check: " + itemStack.getName() + + debugInfo.append( " (Debug-unsold-value-check: " + itemStack.getName() + " qty: " + itemStack.getAmount() + " value: " + dFmt.format( amount ) + ") "); } @@ -1052,7 +1052,7 @@ protected int autoPickup( PrisonMinesBlockBreakEvent pmEvent, if ( count > 0 || autosellTotal > 0 ) { - debugInfo.append( "{br} [autoPickupDrops total: qty: " + count + " value: " + dFmt.format( autosellTotal ) + + debugInfo.append( "{br}|| [autoPickupDrops total: qty: " + count + " value: " + dFmt.format( autosellTotal ) + " unsellableCount: " + autosellUnsellableCount ); if ( nanoTime > 0 ) { @@ -1135,7 +1135,7 @@ public int calculateNormalDrop( PrisonMinesBlockBreakEvent pmEvent ) { sb.insert( 0, "bukkitDropMult=" ); } - pmEvent.getDebugInfo().append( "{br} [normalDrops:: " ).append( sb ).append( "] "); + pmEvent.getDebugInfo().append( "{br}|| [normalDrops:: " ).append( sb ).append( "] "); // Need better drop calculation that is not using the getDrops function. @@ -1186,7 +1186,7 @@ public int calculateNormalDrop( PrisonMinesBlockBreakEvent pmEvent ) { // } - pmEvent.getDebugInfo().append( "{br} " ); +// pmEvent.getDebugInfo().append( "{br}|| " ); double autosellTotal = 0; @@ -1239,7 +1239,7 @@ public int calculateNormalDrop( PrisonMinesBlockBreakEvent pmEvent ) { if ( count > 0 || autosellTotal > 0 ) { - pmEvent.getDebugInfo().append( "{br} [normalDrops total: qty: " + count + " value: " + autosellTotal + "] "); + pmEvent.getDebugInfo().append( "{br}|| [normalDrops total: qty: " + count + " value: " + autosellTotal + "] "); } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/block/OnBlockBreakEventCore.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/block/OnBlockBreakEventCore.java index c4264bb6c..7fe0d5c57 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/block/OnBlockBreakEventCore.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/block/OnBlockBreakEventCore.java @@ -372,7 +372,7 @@ protected boolean validateEvent( PrisonMinesBlockBreakEvent pmEvent ) StringBuilder debugInfo = pmEvent.getDebugInfo(); - debugInfo.append( "{br} validateEvent:: " ); + debugInfo.append( "{br}|| validateEvent:: " ); SpigotBlock sBlockHit = pmEvent.getSpigotBlock(); @@ -777,7 +777,7 @@ else if ( targetExplodedBlock.isMined() ) { } - debugInfo.append( "{br} blocks(" ) + debugInfo.append( " blocks(" ) .append( pmEvent.getBlock() == null ? "0" : "1" ) .append( "+" ) .append( pmEvent.getExplodedBlocks().size() ) @@ -1030,7 +1030,7 @@ else if ( results && pmEvent.getBbPriority().isMonitor() && mine != null ) { } - debugInfo.append( "{br} " ); +// debugInfo.append( "{br}|| " ); return results; } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/block/OnBlockBreakMines.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/block/OnBlockBreakMines.java index 4eb028c6c..a99068edd 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/block/OnBlockBreakMines.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/block/OnBlockBreakMines.java @@ -115,7 +115,7 @@ public String getDebugInfo() { getSpigotBlock().getLocation().toWorldCoordinates(); return String.format( - "{br} EventInfo: %s %s Mine: %s %s %s ", + "{br}|| EventInfo: %s %s Mine: %s %s %s ", getResultsReason().name(), // getBbPriority().name(), getSpigotPlayer().getName(), From bd8a092ac7042f43463f0a8e6e376cb56942753d Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sun, 24 Sep 2023 04:49:23 -0400 Subject: [PATCH 122/151] Prison Support: Added a more secure method and server (privatebin) for submitting server information under prison support submit commands. --- .gitignore | 7 + docs/changelog_v3.3.x.md | 7 +- prison-core/build.gradle | 19 ++ prison-core/lib/json-20230227.jar | Bin 0 -> 72591 bytes prison-core/lib/privatebin-java-api-1.0.2.jar | Bin 0 -> 12599 bytes .../tech/mcprison/prison/PrisonCommand.java | 181 +++++++++--------- .../prison/discord/PrisonPasteChat.java | 58 +++++- prison-spigot/src/main/resources/config.yml | 36 ++++ 8 files changed, 218 insertions(+), 90 deletions(-) create mode 100644 prison-core/lib/json-20230227.jar create mode 100644 prison-core/lib/privatebin-java-api-1.0.2.jar diff --git a/.gitignore b/.gitignore index d1cddf832..57cc6bdb7 100644 --- a/.gitignore +++ b/.gitignore @@ -102,7 +102,14 @@ local.properties *.war *.ear + +# Prison libs: .jar files are usally ignored, so must add these libraries: !/prison-spigot/lib/**/*.jar +!/prison-core/lib/**/*.jar + +# but exclude this directory: +prison-spigot/lib/old/ + # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml hs_err_pid* diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 4424e4fe2..8e2ed53fb 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -23,7 +23,12 @@ These change logs represent the work that has been going on within prison. * **Changed the default color code from `&9` (dark blue) to `&b` (light blue) for debug logging since the dark blue could be difficult to see on some consoles. -**v3.3.0-alpha.15f 2023-09-22** +**v3.3.0-alpha.15f 2023-09-23** + + +* **Prison Support: Added a more secure method and server (privatebin) for submitting server information under prison support submit commands.** +Can now control some of the settings that are used, including password, in the config.yml file. +May need to refresh config.ymml to see now settings. * **MineBombs: validate all mine bombs upon server startup to validate the sound effects, visual effects, and shape based upon the version of spigot that they are running.** diff --git a/prison-core/build.gradle b/prison-core/build.gradle index d158f866a..8c84bad53 100644 --- a/prison-core/build.gradle +++ b/prison-core/build.gradle @@ -25,10 +25,21 @@ compileTestJava.options.encoding = "UTF-8" repositories { mavenCentral() + + //maven { url = "https://jitpack.io" } } dependencies { implementation 'org.apache.commons:commons-lang3:3.12.0' + + //implementation 'com.github.InstantlyMoist:privatebin-java-api:1.0.2' + + //implementation 'org.json:json:20230227' + + implementation fileTree(dir: 'lib', + include: ['privatebin-java-api-1.0.2.jar', + 'json-20230227.jar']) + } /* @@ -46,7 +57,15 @@ shadowJar { // https://mvnrepository.com/artifact/com.google.code.gson/gson include(dependency('com.google.code.gson:gson:2.10.1')) //include(dependency('com.google.code.gson:gson:2.8.6')) + + include(dependency('org.json:json:20230227')) + include(dependency('com.github.InstantlyMoist:privatebin-java-api:*')) } + + relocate 'org.json', 'tech.mcprison.prison.orgjson' + relocate 'com.github.InstantlyMoist', 'tech.mcprison.prison.privatebin8' + + classifier 'API' archiveVersion = null } diff --git a/prison-core/lib/json-20230227.jar b/prison-core/lib/json-20230227.jar new file mode 100644 index 0000000000000000000000000000000000000000..abdb16b76465b44239a6763f8fc7d6b6f19d542d GIT binary patch literal 72591 zcmb5UW0WsXv+voq?cQzM_OET*+PiJrwr$(CZQC|>YyQtUGxwbP%$j@W=BlbURS_$5 zWmJAY8IcOopkQb~P*6}n%~slKK>w|w0f7O@im3?ENy-5jWQF7;0b;KgX`sVgC$0_>7Q)!|_@^-$GR4HTnt^X0 zvR#VF7iBkaa&;{osa*l%RqG3Y9;)uZ1gE5;^CYtU=ydHPf?=-BS5`pB9lF5WF#D)M z^@R?K>3u8niuk43+->dBb^iX2uJ@7Nv*+%;JRKe2k)Gda>^OmFN6BLR@#^N{@1k?3 z3#OM92FEJqPMoZbO;{rvVER{AYoVZ-B{Lp{e#p38lHA|!9|dVhC>RxUCL<6aASf^( zAcg;mQ{MkMPNDya+5Zuzp#OXb3H7fi{>Sb=+W)s9;y>^IhoQBhi>VF6|A{%)|J&Tw z!JPiLqwW8hAN>D?pZ~qHfBR`^{&&voY^~|-9Bl1O9h@vp9m%HZVFrJp3C`=@5fYeS zx>G^<%LJ#uWp5D9y&2IJ7&Wo_<_5*Q!nJlP7ZuQGGU65;1kHH(Bx+E;s6d&%-Hui_uRrwuRTbR=u$UBCbIS#hFuD)*UprT_l@#_lOJ4ECvfjssuE+sh_tgmu{&H`RD60qe5UKs znDc|SE|UP-UAWTW*>9F9GgQJeh_Vu)b-oDp9}Ir`{Qd9%-cLhs0`tkBfMYGQWrtTi zuGdo*pPr!Vo-C(e>{eSGRtQi6En~I&qacP$g%za%@VgLd2b@hIO!qP;G zzLZ}KGag=%7C`K9f?vjUDfdStX3KBFvOGKmyvXU8avj-32`#y<2_wqU=#sdY+H}`X z!e0O>fnk7g=X^+g7+TVSsu>=(L)*Tm;t*3jHj%gnEq4uji8C0R#hnd)-YRK=`VeiN z*}YFwoy%8SzzYbhfny|e;mAo-39#LO!;meR85 zxOlP80WEO8(Cb&3DWBr%ADap)gv8f|JeexCOmD-L5Kz_1nMI3uiVdRtNxb#3%0AlhDRte#kS8i(V;8{-WJ| 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 literal 0 HcmV?d00001 diff --git a/prison-core/lib/privatebin-java-api-1.0.2.jar b/prison-core/lib/privatebin-java-api-1.0.2.jar new file mode 100644 index 0000000000000000000000000000000000000000..037b7b22ea026544b8b1934682f41ef9cb53361d GIT binary patch literal 12599 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 C69IYv literal 0 HcmV?d00001 diff --git a/prison-core/src/main/java/tech/mcprison/prison/PrisonCommand.java b/prison-core/src/main/java/tech/mcprison/prison/PrisonCommand.java index 7dd5c941e..78eaa4ff4 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/PrisonCommand.java +++ b/prison-core/src/main/java/tech/mcprison/prison/PrisonCommand.java @@ -1426,7 +1426,11 @@ public void supportSubmitVersion(CommandSender sender } - StringBuilder text = Prison.get().getPrisonStatsUtil().getSupportSubmitVersionData(); + StringBuilder text = new StringBuilder(); + + text.append( "NOTE: Listeners and Configs information is provided below.\n\n" ); + + text.append( Prison.get().getPrisonStatsUtil().getSupportSubmitVersionData() ); int idx = text.indexOf("{br}"); while ( idx != -1 ) { @@ -1464,6 +1468,9 @@ public void supportSubmitVersion(CommandSender sender // } + + text.append( Prison.get().getPrisonStatsUtil().getSupportSubmitConfigsData() ); + if ( getSupportFile() != null ) { @@ -1498,55 +1505,55 @@ public void supportSubmitVersion(CommandSender sender - @Command(identifier = "prison support submit configs", - description = "For Prison support: This will copy the contents of Prison's config " + - "file to paste.helpch.at so it can be easily shared with Prison's " + - "support staff. This will include the following: config.yml plugin.yml " + - "autoFeaturesConfig.yml modules.yml module_conf/mines/config.json " + - "SellAllConfig.yml GuiConfig.yml backpacks/backpacksconfig.yml", - onlyPlayers = false, permissions = "prison.debug" ) - public void supportSubmitConfigs(CommandSender sender - ) { - - - if ( getSupportName() == null || getSupportName().trim().isEmpty() ) { - sender.sendMessage( "The support name needs to be set prior to using this command." ); - sender.sendMessage( "Use &7/prison support setSupportName help" ); - - return; - } - - StringBuilder text = Prison.get().getPrisonStatsUtil().getSupportSubmitConfigsData(); - - - - if ( getSupportFile() != null ) { - - getSupportFile().saveToSupportFile( text, getSupportName() ); - - sender.sendMessage(" - Support 'configs' data was just added to the support output file." ); - sender.sendMessage( getSupportFile().getFileStats( text.length() ) ); - } - else { - - PrisonPasteChat pasteChat = new PrisonPasteChat( getSupportName(), getSupportURLs() ); - - String helpURL = pasteChat.postKeepColorCodes( text.toString() ); - - getSupportURLs().put( "Submit configs:", helpURL ); - - if ( helpURL != null ) { - - sender.sendMessage( "Prison's support information has been pasted. Copy and " + - "paste this URL in to Prison's Discord server." ); - sender.sendMessage( String.format( "Paste this URL: %s", helpURL )); - } - else { - sender.sendMessage( "There was an error trying to generate the paste.helpch.at URL." ); - } - - } - } +// @Command(identifier = "prison support submit configs", +// description = "For Prison support: This will copy the contents of Prison's config " + +// "file to paste.helpch.at so it can be easily shared with Prison's " + +// "support staff. This will include the following: config.yml plugin.yml " + +// "autoFeaturesConfig.yml modules.yml module_conf/mines/config.json " + +// "SellAllConfig.yml GuiConfig.yml backpacks/backpacksconfig.yml", +// onlyPlayers = false, permissions = "prison.debug" ) +// public void supportSubmitConfigs(CommandSender sender +// ) { +// +// +// if ( getSupportName() == null || getSupportName().trim().isEmpty() ) { +// sender.sendMessage( "The support name needs to be set prior to using this command." ); +// sender.sendMessage( "Use &7/prison support setSupportName help" ); +// +// return; +// } +// +// StringBuilder text = Prison.get().getPrisonStatsUtil().getSupportSubmitConfigsData(); +// +// +// +// if ( getSupportFile() != null ) { +// +// getSupportFile().saveToSupportFile( text, getSupportName() ); +// +// sender.sendMessage(" - Support 'configs' data was just added to the support output file." ); +// sender.sendMessage( getSupportFile().getFileStats( text.length() ) ); +// } +// else { +// +// PrisonPasteChat pasteChat = new PrisonPasteChat( getSupportName(), getSupportURLs() ); +// +// String helpURL = pasteChat.postKeepColorCodes( text.toString() ); +// +// getSupportURLs().put( "Submit configs:", helpURL ); +// +// if ( helpURL != null ) { +// +// sender.sendMessage( "Prison's support information has been pasted. Copy and " + +// "paste this URL in to Prison's Discord server." ); +// sender.sendMessage( String.format( "Paste this URL: %s", helpURL )); +// } +// else { +// sender.sendMessage( "There was an error trying to generate the paste.helpch.at URL." ); +// } +// +// } +// } @Command(identifier = "prison support submit ranks", @@ -1912,43 +1919,43 @@ private void readFileToStringBulider( File textFile, StringBuilder text ) } - @Command(identifier = "prison support submit listeners", - description = "For Prison support: This will copy the server's active listeners " + - "for blockBreak, chat, and playerInteracts to paste.helpch.at so it can be " + - "easily shared with Prison's support staff.", - onlyPlayers = false, permissions = "prison.debug" ) - public void supportSubmitListeners(CommandSender sender - ) { - - - if ( getSupportName() == null || getSupportName().trim().isEmpty() ) { - sender.sendMessage( "The support name needs to be set prior to using this command." ); - sender.sendMessage( "Use &7/prison support setSupportName help" ); - - return; - } - - - StringBuilder text = Prison.get().getPrisonStatsUtil().getSupportSubmitListenersData( "all" ); - - PrisonPasteChat pasteChat = new PrisonPasteChat( getSupportName(), getSupportURLs() ); - - String helpURL = pasteChat.post( text.toString() ); - - getSupportURLs().put( "Submit Listeners:", helpURL ); - - if ( helpURL != null ) { - - sender.sendMessage( "Prison's support information has been pasted. Copy and " + - "paste this URL in to Prison's Discord server." ); - sender.sendMessage( String.format( "Paste this URL: %s", helpURL )); - } - else { - sender.sendMessage( "There was an error trying to generate the paste.helpch.at URL." ); - } - - - } +// @Command(identifier = "prison support submit listeners", +// description = "For Prison support: This will copy the server's active listeners " + +// "for blockBreak, chat, and playerInteracts to paste.helpch.at so it can be " + +// "easily shared with Prison's support staff.", +// onlyPlayers = false, permissions = "prison.debug" ) +// public void supportSubmitListeners(CommandSender sender +// ) { +// +// +// if ( getSupportName() == null || getSupportName().trim().isEmpty() ) { +// sender.sendMessage( "The support name needs to be set prior to using this command." ); +// sender.sendMessage( "Use &7/prison support setSupportName help" ); +// +// return; +// } +// +// +// StringBuilder text = Prison.get().getPrisonStatsUtil().getSupportSubmitListenersData( "all" ); +// +// PrisonPasteChat pasteChat = new PrisonPasteChat( getSupportName(), getSupportURLs() ); +// +// String helpURL = pasteChat.post( text.toString() ); +// +// getSupportURLs().put( "Submit Listeners:", helpURL ); +// +// if ( helpURL != null ) { +// +// sender.sendMessage( "Prison's support information has been pasted. Copy and " + +// "paste this URL in to Prison's Discord server." ); +// sender.sendMessage( String.format( "Paste this URL: %s", helpURL )); +// } +// else { +// sender.sendMessage( "There was an error trying to generate the paste.helpch.at URL." ); +// } +// +// +// } diff --git a/prison-core/src/main/java/tech/mcprison/prison/discord/PrisonPasteChat.java b/prison-core/src/main/java/tech/mcprison/prison/discord/PrisonPasteChat.java index 7d4f53db8..7c0642ecd 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/discord/PrisonPasteChat.java +++ b/prison-core/src/main/java/tech/mcprison/prison/discord/PrisonPasteChat.java @@ -17,6 +17,9 @@ import com.google.gson.Gson; import com.google.gson.JsonObject; +import nl.kyllian.enums.Expire; +import nl.kyllian.enums.PasteFormat; +import nl.kyllian.models.Paste; import tech.mcprison.prison.Prison; import tech.mcprison.prison.output.Output; import tech.mcprison.prison.util.Text; @@ -107,7 +110,24 @@ public String post( String text, boolean raw, boolean keepColorCodes ) { cleanedText = addHeaders( cleanedText ); - results = postPaste( cleanedText, raw ); + String service = Prison.get().getPlatform() + .getConfigString( "prison-support.submit-service", "PRIVATEBIN-NET" ); + + switch ( service ) { + case "PRIVATEBIN-NET": + + results = postPrivateBin( cleanedText, raw ); + break; + + case "PASTE-HELPCHAT": + + results = postPasteHelpchAt( cleanedText, raw ); + break; + + default: + break; + } + } catch (Exception e) { Output.get().logInfo( "PrisonPasteChat: Failed to paste to paste.helpch.at. " + @@ -215,8 +235,42 @@ private String padSpaces( String keyName ) { return (keyName + " ").substring( 0,18 ); } - private String postPaste( String text, boolean raw ) + + private String postPrivateBin( String text, boolean raw ) throws IOException { + + String expire = Prison.get().getPlatform().getConfigString( "prison-support.expire", "one_week" ); + String password = Prison.get().getPlatform().getConfigString( "prison-support.password", "PrisonSupport" ); + + Paste paste = new Paste("https://privatebin.net") + .setMessage( text ) + .setExpire( getExpire( expire ) ) + .setPasteFormat( PasteFormat.PLAINTEXT ) + .setUserPassword( password ) +// .removeIps() + .encrypt(); + + String pasteUrl = paste.send(); + + return pasteUrl; + } + + private Expire getExpire( String value ) { + Expire results = Expire.ONE_WEEK; + + for ( Expire ex : Expire.values() ) { + if ( ex.name().equalsIgnoreCase( value ) ) { + results = ex; + break; + } + } + + return results; + } + + private String postPasteHelpchAt( String text, boolean raw ) + throws IOException { + String results = null; String rawJson = null; diff --git a/prison-spigot/src/main/resources/config.yml b/prison-spigot/src/main/resources/config.yml index 997b70c53..73693345a 100644 --- a/prison-spigot/src/main/resources/config.yml +++ b/prison-spigot/src/main/resources/config.yml @@ -23,6 +23,42 @@ debug: false + +# Prison support: +# Prison has a lot of built in tools to help us provide you with a higher degree of +# support, and to help make it easier for you. +# One of these features, is the ability to submit details about your server's +# Prison setup so we can review many of the features and settings without having +# to ask tons of questions. It also helps to improve the quality of our help by +# eliminating miscommunication and trying to provide answers off of incorrect +# settings. +# Prison is able to gather various informmation and send it in one or more documents +# and then provide you with one URL to copy and paste to share with us. +# +# submit-service: +# PRIVATEBIN-NET - New default option - This uses an encrypted payload and no one +# can read the posts without the password. All posts are eligable +# to be purged in 1 week. +# URL: privatebin.net - hosted in sweeden +# Options: +# expire: [one_week, one_day, one_hour] +# password: PrisonSupport - default - Do not change this unless you tell +# support team what it is. Odds of someone reading your post is +# limited to only those who may be on our support discord server. +# PASTE-HELPCHAT - This was the default serivce. We no longer recommend using this +# service because: the posts do not expire and are not deletable, +# anyone with the URL can view the contents (improbable the can +# find it due to random URL), and limited to 400k. +# URL: paste.helpch.at - Ran by the folks who publish placeholderAPI. +# Options: none\ +# +prison-support: + submit-service: PRIVATEBIN-NET + expire: 1week + password: PrisonSupport + + + # Upon server startup prison will check to see if a newer version has been released. check-updates: true From 0fc3e6c6054f8d898905bbe1a74981ed5e8632fe Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sun, 24 Sep 2023 18:10:15 -0400 Subject: [PATCH 123/151] TopNPlayer: Task could not startup if ranks are enabled but there are no default ranks. Log a message in the console that the task cannot start because ranks are enabled and there are no ranks. Request that Ranks module is disabled, or add default ranks and then restart the server. --- docs/changelog_v3.3.x.md | 7 ++++++- .../mcprison/prison/ranks/data/TopNPlayers.java | 14 +++++++++++++- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 8e2ed53fb..384dde584 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -23,7 +23,12 @@ These change logs represent the work that has been going on within prison. * **Changed the default color code from `&9` (dark blue) to `&b` (light blue) for debug logging since the dark blue could be difficult to see on some consoles. -**v3.3.0-alpha.15f 2023-09-23** +**v3.3.0-alpha.15f 2023-09-24** + + +* **TopNPlayer: Task could not startup if ranks are enabled but there are no default ranks.** +Log a message in the console that the task cannot start because ranks are enabled and there are no ranks. +Request that Ranks module is disabled, or add default ranks and then restart the server. * **Prison Support: Added a more secure method and server (privatebin) for submitting server information under prison support submit commands.** diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/TopNPlayers.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/TopNPlayers.java index b11021aae..de0a28878 100644 --- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/TopNPlayers.java +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/TopNPlayers.java @@ -12,6 +12,7 @@ import tech.mcprison.prison.file.FileIOData; import tech.mcprison.prison.file.JsonFileIO; import tech.mcprison.prison.internal.Player; +import tech.mcprison.prison.output.Output; import tech.mcprison.prison.ranks.PrisonRanks; import tech.mcprison.prison.ranks.tasks.TopNPlayerUpdateAsyncTask; @@ -132,7 +133,9 @@ private void launchTopNPlayerUpdateAsyncTask() { if ( PrisonRanks.getInstance() != null && PrisonRanks.getInstance().isEnabled() && - PrisonRanks.getInstance().getPlayerManager() != null ) { + PrisonRanks.getInstance().getPlayerManager() != null && + PrisonRanks.getInstance().getDefaultLadder().getRanks().size() > 0 + ) { Long delayTicks = Prison.get().getPlatform().getConfigLong( "topNPlayers.refresh.delay-ticks", DELAY_THIRTY_SECONDS_TICKS ); @@ -142,6 +145,15 @@ private void launchTopNPlayerUpdateAsyncTask() { TopNPlayerUpdateAsyncTask.submitTaskTimerAsync( this, delayTicks, intervalTicks ); } + else if ( PrisonRanks.getInstance() != null && + PrisonRanks.getInstance().isEnabled() && + PrisonRanks.getInstance().getDefaultLadder().getRanks().size() == 0 ) { + + Output.get().logWarn( "TopNPlayer: Cannot start the TopNPlayer task. Ranks are " + + "enabled, but there are no default ranks setup. " + + "Either turn off the Ranks Module, or add ranks and " + + "then restart the server to get the TopNPlayer task running."); + } } From 0442e3d6e2c9c0d655323ae0fda4a357dc3834f8 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Mon, 25 Sep 2023 22:59:56 -0400 Subject: [PATCH 124/151] Cleanup the '/ranks list' to add mines and better format the name, tag, and cost. Also removed rankId which is not important anymore. --- docs/changelog_v3.3.x.md | 6 +- .../prison/ranks/commands/RanksCommands.java | 69 +++++++++++++++---- 2 files changed, 60 insertions(+), 15 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 384dde584..e9611cf14 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -14,7 +14,11 @@ These change logs represent the work that has been going on within prison. -# 3.3.0-alpha.15f 2023-09-22 +# 3.3.0-alpha.15f 2023-09-25 + + +* **Cleanup the '/ranks list' to add mines and better format the name, tag, and cost.** +Also removed rankId which is not important anymore. * **Auto features: change a few of the new line breaks so there are fewer.** diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/RanksCommands.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/RanksCommands.java index c9bfc6a3e..3dcb370cd 100644 --- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/RanksCommands.java +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/RanksCommands.java @@ -965,23 +965,35 @@ private ChatDisplay listRanksOnLadder( RankLadder ladder, boolean hasPerm, RankP new BulletedListComponent.BulletedListBuilder(); DecimalFormat fFmt = Prison.get().getDecimalFormat("#,##0.0000"); + DecimalFormat iFmt = Prison.get().getDecimalFormat("#,##0"); // Here's the deal... With color codes, Java's String.format() cannot detect the correct // length of a tag. So go through all tags, strip the colors, and see how long they are. // We need to know the max length so we can pad the others with periods to align all costs. int maxRankNameSize = 0; int maxRankTagNoColorSize = 0; + int maxRankCostSize = 0; + for (Rank rank : ladder.getRanks()) { - if ( rank.getName().length() > maxRankNameSize ) { - maxRankNameSize = rank.getName().length(); + String nameNoColor = Text.stripColor( rank.getName() ); + if ( nameNoColor.length() > maxRankNameSize ) { + maxRankNameSize = nameNoColor.length(); } String tag = rank.getTag() == null ? "" : rank.getTag(); String tagNoColor = Text.stripColor( tag ); if ( tagNoColor.length() > maxRankTagNoColorSize ) { maxRankTagNoColorSize = tagNoColor.length(); } + + int costSize = iFmt.format( rank.getRawRankCost() ).length(); + if ( costSize > maxRankCostSize ) { + maxRankCostSize = costSize; + } } + maxRankCostSize++; + String nameStringFormat = "%-" + maxRankNameSize + "s "; + String tagStringFormat = "%-" + maxRankTagNoColorSize + "s "; RankPlayerFactory rankPlayerFactory = new RankPlayerFactory(); @@ -991,12 +1003,24 @@ private ChatDisplay listRanksOnLadder( RankLadder ladder, boolean hasPerm, RankP boolean defaultRank = (LadderManager.LADDER_DEFAULT.equalsIgnoreCase( ladder.getName() ) && first); + String nameNoColor = Text.stripColor( rank.getName() ); + String tag = rank.getTag() == null ? "" : rank.getTag(); + String tagNoColor = Text.stripColor( tag ); +// String rankCost = iFmt.format( rank.getRawRankCost() ); + + String nameFormatted = String.format( nameStringFormat, nameNoColor ); + nameFormatted = nameFormatted.replace( nameNoColor, rank.getName() ); + + String tagFormatted = String.format( tagStringFormat, tagNoColor ); + tagFormatted = tagFormatted.replace( tagNoColor, tag ); + + // Since the formatting gets confused with color formatting, we must // strip the color codes and then inject them back in. So instead, this // provides the formatting rules for both name and rank tag, thus // taking in to consideration the color codes and if the hasPerms is // true. To prevent variable space issues, the difference is filled in with periods. - String textRankNameString = padRankName( rank, maxRankNameSize, maxRankTagNoColorSize, hasPerm ); +// String textRankNameString = padRankName( rank, maxRankNameSize, maxRankTagNoColorSize, hasPerm ); // // trick it to deal correctly with tags. Tags can have many colors, but // // it will render as if it had the colors stripped. So first generate the @@ -1051,26 +1075,43 @@ private ChatDisplay listRanksOnLadder( RankLadder ladder, boolean hasPerm, RankP String players = rank.getPlayers().size() == 0 ? "" : " &dPlayers: &3" + rank.getPlayers().size(); - String rawRankId = ( hasPerm ? - String.format( "(rankId: %s%s%s)", - Integer.toString( rank.getId() ), - (rank.getRankPrior() == null ? "" : " -"), - (rank.getRankNext() == null ? "" : " +") ) - : ""); +// String rawRankId = ( hasPerm ? +// String.format( "(rankId: %s%s%s)", +// Integer.toString( rank.getId() ), +// (rank.getRankPrior() == null ? "" : " -"), +// (rank.getRankNext() == null ? "" : " +") ) +// : ""); + + + StringBuilder minesSb = new StringBuilder(); + for ( ModuleElement mine : rank.getMines() ) { + if ( minesSb.length() > 0 ) { + minesSb.append( "&6,&7" ); + } + minesSb.append( mine.getTag() ); + } + if ( minesSb.length() > 0 ) { + minesSb.insert( 0, " &6Mines: &7" ); +// minesSb.append( "8" ); + } String text = - String.format("&3%s &7%-17s%s&7 &b%s &3%s %s&7 %s%s", - textRankNameString, - Text.numberToDollars( rankCost ), + String.format("&3%s %s &7%" + maxRankCostSize + "s &a%s &b%s %s&7 %s%s%s", + nameFormatted, + tagFormatted, + + iFmt.format( rankCost ), +// Text.numberToDollars( rankCost ), (defaultRank ? "{def}" : ""), rankMultiplier, - rawRankId, +// rawRankId, textCurrency, textCmdCount, - players + players, + minesSb.toString() ); // // Swap the color tag back in: From 276121508449e05edc1c337a9808603f4fadf063 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 30 Sep 2023 16:40:57 -0400 Subject: [PATCH 125/151] Autosell: Setup the SpigotPlayer object to support functions to identify if the player has autosell enabled. This is used in a couple of places to eliminate redundancy. Fixes a problem with the block break event not also checking to see if the player has toggled their autosell status for the forced sell after the event is processed, and also the delayed sell. --- docs/changelog_v3.3.x.md | 6 +- .../autofeatures/AutoManagerFeatures.java | 51 +++++----- .../events/AutoManagerBlockBreakEvents.java | 26 ++++- .../prison/spigot/game/SpigotPlayer.java | 96 +++++++++++++++++++ 4 files changed, 153 insertions(+), 26 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index e9611cf14..6378506b2 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -14,7 +14,11 @@ These change logs represent the work that has been going on within prison. -# 3.3.0-alpha.15f 2023-09-25 +# 3.3.0-alpha.15f 2023-09-30 + + +* **Autosell: Setup the SpigotPlayer object to support functions to identify if the player has autosell enabled. This is used in a couple of places to eliminate redundancy.** +Fixes a problem with the block break event not also checking to see if the player has toggled their autosell status for the forced sell after the event is processed, and also the delayed sell. * **Cleanup the '/ranks list' to add mines and better format the name, tag, and cost.** diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerFeatures.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerFeatures.java index cba4abe45..a8b96a1ee 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerFeatures.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerFeatures.java @@ -891,23 +891,25 @@ protected int autoPickup( PrisonMinesBlockBreakEvent pmEvent, SpigotPrison.getInstance().isSellAllEnabled(); - boolean isPlayerAutoSellTurnedOff = SellAllUtil.get().isAutoSellPerUserToggleable && - !SellAllUtil.get().isSellallPlayerUserToggleEnabled( - pmEvent.getSpigotPlayer().getWrapper() ); - - if ( isPlayerAutoSellTurnedOff ) { - debugInfo.append( Output.get().getColorCodeWarning() ); - debugInfo.append( "(Player toggled off autosell) " ); - debugInfo.append( Output.get().getColorCodeDebug() ); - } +// boolean isPlayerAutoSellTurnedOff = SellAllUtil.get().isAutoSellPerUserToggleable && +// !SellAllUtil.get().isSellallPlayerUserToggleEnabled( +// pmEvent.getSpigotPlayer().getWrapper() ); +// +// if ( isPlayerAutoSellTurnedOff ) { +// debugInfo.append( Output.get().getColorCodeWarning() ); +// debugInfo.append( "(Player toggled off autosell) " ); +// debugInfo.append( Output.get().getColorCodeDebug() ); +// } +// +// // This will return true (allow autosell) unless players can toggle autosell and they turned it off: +// // This is to be used with other auto sell setting, but never on it's own: +// boolean isPlayerAutosellEnabled = +// isSellallEnabled && +// (!SellAllUtil.get().isAutoSellPerUserToggleable || +// SellAllUtil.get().isSellallPlayerUserToggleEnabled( +// pmEvent.getSpigotPlayer().getWrapper() )); - // This will return true (allow autosell) unless players can toggle autosell and they turned it off: - // This is to be used with other auto sell setting, but never on it's own: - boolean isPlayerAutosellEnabled = - isSellallEnabled && - (!SellAllUtil.get().isAutoSellPerUserToggleable || - SellAllUtil.get().isSellallPlayerUserToggleEnabled( - pmEvent.getSpigotPlayer().getWrapper() )); + boolean isPlayerAutosellEnabled = pmEvent.getSpigotPlayer().isAutoSellEnabled( pmEvent.getDebugInfo() ); // In the event, forceAutoSell is enabled, which means the drops must be sold. @@ -921,13 +923,16 @@ protected int autoPickup( PrisonMinesBlockBreakEvent pmEvent, isBoolean(AutoFeatures.isAutoSellPerBlockBreakEnabled); // AutoFeature's autosell per block break - per player perms setting - boolean autoSellByPerm = - isPlayerAutosellEnabled && - !player.isOp() && - isBoolean(AutoFeatures.isAutoSellPerBlockBreakEnabled) && - !"disable".equalsIgnoreCase( getMessage( AutoFeatures.permissionAutoSellPerBlockBreakEnabled ) ) && - !"false".equalsIgnoreCase( getMessage( AutoFeatures.permissionAutoSellPerBlockBreakEnabled ) ) && - player.hasPermission( getMessage( AutoFeatures.permissionAutoSellPerBlockBreakEnabled ) ); +// boolean autoSellByPerm = +// isPlayerAutosellEnabled && +// !player.isOp() && +// isBoolean(AutoFeatures.isAutoSellPerBlockBreakEnabled) && +// !"disable".equalsIgnoreCase( getMessage( AutoFeatures.permissionAutoSellPerBlockBreakEnabled ) ) && +// !"false".equalsIgnoreCase( getMessage( AutoFeatures.permissionAutoSellPerBlockBreakEnabled ) ) && +// player.hasPermission( getMessage( AutoFeatures.permissionAutoSellPerBlockBreakEnabled ) ); + + boolean autoSellByPerm = pmEvent.getSpigotPlayer().isAutoSellByPermEnabled( isPlayerAutosellEnabled ); + // Try to autosell if enabled in any of the following ways: boolean autoSell = ( forceAutoSell || autoSellBySettings || autoSellByPerm ); diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerBlockBreakEvents.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerBlockBreakEvents.java index fa1dbf9df..3fecf1bd8 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerBlockBreakEvents.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerBlockBreakEvents.java @@ -502,15 +502,37 @@ else if ( cancelBy == EventListenerCancelBy.drops ) { // } } + + + boolean isPlayerAutosellEnabled = pmEvent.getSpigotPlayer().isAutoSellEnabled( pmEvent.getDebugInfo() ); + + +// // In the event, forceAutoSell is enabled, which means the drops must be sold. +// // The player's toggle cannot disable this. +// boolean forceAutoSell = isSellallEnabled && pmEvent.isForceAutoSell(); +// + +// // AutoFeature's autosell per block break - global setting +// boolean autoSellBySettings = +// isPlayerAutosellEnabled && +// isBoolean(AutoFeatures.isAutoSellPerBlockBreakEnabled); + + + boolean isPlayerAutoSellByPerm = pmEvent.getSpigotPlayer().isAutoSellByPermEnabled( isPlayerAutosellEnabled ); + + + - if ( isBoolean( AutoFeatures.isForceSellAllOnInventoryWhenBukkitBlockBreakEventFires ) ) { + if ( isBoolean( AutoFeatures.isForceSellAllOnInventoryWhenBukkitBlockBreakEventFires ) && + ( isPlayerAutosellEnabled || isPlayerAutoSellByPerm )) { pmEvent.getDebugInfo().append( Output.get().getColorCodeWarning()); pmEvent.performSellAllOnPlayerInventoryLogged( "FORCED BlockBreakEvent sellall"); pmEvent.getDebugInfo().append( Output.get().getColorCodeDebug()); } - if ( isBoolean( AutoFeatures.isEnabledDelayedSellAllOnInventoryWhenBukkitBlockBreakEventFires ) ) { + if ( isBoolean( AutoFeatures.isEnabledDelayedSellAllOnInventoryWhenBukkitBlockBreakEventFires ) && + ( isPlayerAutosellEnabled || isPlayerAutoSellByPerm ) ) { if ( !getDelayedSellallPlayers().contains( pmEvent.getSpigotPlayer() ) ) { diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotPlayer.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotPlayer.java index bb671acd4..d09d7a6d9 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotPlayer.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotPlayer.java @@ -46,13 +46,16 @@ import tech.mcprison.prison.internal.inventory.Inventory; import tech.mcprison.prison.internal.scoreboard.Scoreboard; import tech.mcprison.prison.mines.data.Mine; +import tech.mcprison.prison.output.Output; import tech.mcprison.prison.ranks.PrisonRanks; import tech.mcprison.prison.ranks.data.RankPlayer; +import tech.mcprison.prison.spigot.SpigotPrison; import tech.mcprison.prison.spigot.SpigotUtil; import tech.mcprison.prison.spigot.block.SpigotBlock; import tech.mcprison.prison.spigot.compat.SpigotCompatibility; import tech.mcprison.prison.spigot.inventory.SpigotPlayerInventory; import tech.mcprison.prison.spigot.scoreboard.SpigotScoreboard; +import tech.mcprison.prison.spigot.sellall.SellAllUtil; import tech.mcprison.prison.spigot.utils.tasks.PlayerMessagingTask; import tech.mcprison.prison.util.Gamemode; import tech.mcprison.prison.util.Location; @@ -844,5 +847,98 @@ public boolean isInventoryFull() { return results; } + /** + *

This function will identify if the player is able to have + * autosell enabled for them. This will take in to consideration + * global settings, and also if they have toggled off their + * autosell capabilities ('/sellall autoSellToggle`). + *

+ * + * @return + */ + public boolean isAutoSellEnabled() { + return isAutoSellEnabled( null ); + } + public boolean isAutoSellEnabled( StringBuilder debugInfo ) { + + boolean isSellallEnabled = SellAllUtil.get() != null && + SpigotPrison.getInstance().isSellAllEnabled(); + + boolean isAutoSellPerUserToggleable = SellAllUtil.get().isAutoSellPerUserToggleable; + + boolean isPlayerAutoSellTurnedOff = isAutoSellPerUserToggleable && + !SellAllUtil.get().isSellallPlayerUserToggleEnabled( + getWrapper() ); + + if ( debugInfo != null && isPlayerAutoSellTurnedOff ) { + debugInfo.append( Output.get().getColorCodeWarning() ); + debugInfo.append( "(Player toggled off autosell) " ); + debugInfo.append( Output.get().getColorCodeDebug() ); + } + + // This will return true (allow autosell) unless players can toggle autosell and they turned it off: + // This is to be used with other auto sell setting, but never on it's own: + boolean isPlayerAutosellEnabled = + isSellallEnabled && + ( !isAutoSellPerUserToggleable || + isPlayerAutoSellTurnedOff ); + + return isPlayerAutosellEnabled; + } + + + /** + *

This will check to see if the player has the perms enabled + * for autosell. + *

+ * + *

If the function 'isAutoSellEnabled()' has already + * been called, you can also pass that in as a parameter so it does + * not have to be recalculated. + *

+ * + * @return + */ + public boolean isAutoSellByPermEnabled() { + return isAutoSellByPermEnabled( isAutoSellEnabled() ); + } + + /** + *

This will check to see if the player has the perms enabled + * for autosell. + *

+ * + *

If the function 'isAutoSellEnabled()' has already + * been called, you can also pass that in as a parameter so it does + * not have to be recalculated. + *

+ * + * @param isPlayerAutosellEnabled + * @return + */ + public boolean isAutoSellByPermEnabled( boolean isPlayerAutosellEnabled ) { + + boolean autoSellByPerm = false; + + AutoFeaturesWrapper afw = AutoFeaturesWrapper.getInstance(); + + boolean isSellallEnabled = SellAllUtil.get() != null && + SpigotPrison.getInstance().isSellAllEnabled(); + + if ( isSellallEnabled && isPlayerAutosellEnabled && !isOp() ) { + + String perm = afw.getMessage( AutoFeatures.permissionAutoSellPerBlockBreakEnabled ); + + autoSellByPerm = + + afw.isBoolean(AutoFeatures.isAutoSellPerBlockBreakEnabled) && + !"disable".equalsIgnoreCase( perm ) && + !"false".equalsIgnoreCase( perm ) && + hasPermission( perm ); + } + + + return autoSellByPerm; + } } From 4fbeaaaf313652f3da39a264a784cc4ea2f4574b Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sun, 1 Oct 2023 22:14:13 -0400 Subject: [PATCH 126/151] Placeholders: Added the ability to specify a player name in all placeholder attributes. This can allow the use of placeholders that are player centric in plugins that cannot support player based placeholder requests. --- docs/changelog_v3.3.x.md | 6 ++- docs/prison_docs_310_guide_placeholders.md | 46 +++++++++++++++---- .../placeholders/PlaceholderAttribute.java | 3 ++ .../placeholders/PlaceholderAttributeBar.java | 25 ++++++++++ .../PlaceholderAttributeNumberFormat.java | 25 ++++++++++ .../PlaceholderAttributeText.java | 24 ++++++++++ .../placeholders/PlaceholderIdentifier.java | 30 ++++++++++++ .../placeholder/SpigotPlaceholders.java | 2 +- 8 files changed, 151 insertions(+), 10 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 6378506b2..0cc379e08 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -14,7 +14,11 @@ These change logs represent the work that has been going on within prison. -# 3.3.0-alpha.15f 2023-09-30 +# 3.3.0-alpha.15f 2023-10-01 + + +* **Placeholders: Added the ability to specify a player name in all placeholder attributes.** +This can allow the use of placeholders that are player centric in plugins that cannot support player based placeholder requests. * **Autosell: Setup the SpigotPlayer object to support functions to identify if the player has autosell enabled. This is used in a couple of places to eliminate redundancy.** diff --git a/docs/prison_docs_310_guide_placeholders.md b/docs/prison_docs_310_guide_placeholders.md index 1d9b8707e..688457d92 100644 --- a/docs/prison_docs_310_guide_placeholders.md +++ b/docs/prison_docs_310_guide_placeholders.md @@ -7,7 +7,7 @@ This document covers different aspects of placeholders within Prison. It explains how they work, how to use them, and different ways to use them. -*Documented updated: 2022-08-14* +*Documented updated: 2023-10-01*
@@ -59,8 +59,13 @@ Sub-command listing of all placeholders commands: * **/prison placeholders stats** -> A new command that currently only shows what placeholders have been hitting prison and their total hit count and the total average duration to process. This tool provides a simple pre-cache to more quickly identify which is the correct placeholder to use with the raw placeholder text. This even include bad placeholder hits so the pre-cache can bypass processing of the junk, which improves server performance. Eventually this will also include a placeholder value cache. +> A new command that currently only shows what placeholders have been hitting prison and their total hit count and the total average duration to process. This tool provides a simple pre-cache to more quickly identify which is the correct placeholder to use with the raw placeholder text. This even includes bad placeholder hits so the pre-cache can bypass processing of the junk, which improves server performance. Eventually this will also include a placeholder value cache. +> The placeholder cache helps reduce the cost of resolving the correct placeholder. + +> To clear and reset the placeholder cache, use the command `/prison placeholders stats resetCache`. + +> NOTE: Viewing and resetting the placeholder cache/stats is a good way to debug possible placeholder problems. This can confirm if prison is getting requests for the given placeholder, or if a placeholder that you're using is bad or incorrect. * **/prison placeholders reload** @@ -219,6 +224,8 @@ There are actually two major kinds of player based placeholders; a third type is The other player based placeholders, which complements the Rank Placeholders, are the ladder placeholders that narrows the ranks down to a specific ladder. So with our example above, if you only want the ranks from the *default* ladder, that is now possible. Also you can control the order they appear by ordering the ladder placeholders in a specific sequence. +NOTE: Player based placeholders can now be used with non-player placeholders by using a placeholder attribute's `player=` attribute. + The Mine based placeholders provide details about mines, and the mine name becomes part of the placeholder name. Out of all of the possible mine based placeholders, each one is duplicated for each mine. So, in rough terms, if there are different mine placeholders and you have 40 mines, then prison will generate about 400 place holders: 40 mines x 10 placeholders each = 400 placeholders for prison. The same applies to the ladder placeholders as the mine placeholders; for every ladder, there will be a specific placeholder that represents each ladder. @@ -245,6 +252,9 @@ Placeholders within prison can now be dynamically customized without having to m The **Placeholder Attributes** is additional text that is added at the end of a placeholder but within the escape characters. The placeholder attribute always begins with a double colon `::` and each parameter is separated with a single colon `:`. Some placeholders cannot use the attributes, and not all attributes can be used on a placeholder. See additional information below that pertains to each attribute. +**Player based placeholders** require player based requests that includes the player. Plugins that provide player based context would be like chat prefixes, scoreboards, and other placeholder consumers that need to use the player based placeholders. Some examples of placeholder consumers that will not have player based contexts, are with scoreboards and some script environments; these requests for player based placeholders would normally fail under regular conditions. To use player based placeholders with plugins that cannot support the player, you can solve this issue with the use of placeholder attributes with the **player=** attribute. See notes below on all placeholder attribute types. + + As of v3.3.0-alpha.11h one placeholder can have more than one Placeholder Attribute, but they have to be of a different type. At this time, this really is not beneficial since the Placeholder Attributes are specific to a certain type of data. But this opens the door to future possibilities that are not possible currently, such as hybrid between a bar graph with a value super-imposed on top of it. @@ -276,6 +286,12 @@ A few Examples using Placeholder Attributes: * **OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOxxxxxxxx** +* `{prison_rank_tag::text:player=RoyalBlueRanger}` - When used in non-player supported plugins, such as holographic displays, this will enable the use of player-based placeholders for the specified player. + + +* `{prison_rankup_cost_remaining_formatted::nFormat:player=RoyalBlueRanger}` - When used in non-player supported plugins, such as holographic displays, this will enable the use of player-based placeholders for the specified player. + + The examples above don't show the color for the bar graphs, but here is a screen print that uses a prison command to test the placeholders dynamically within prison: @@ -305,13 +321,14 @@ The Numeric Format attribute will only work on placeholders that return plain nu Example of this attribute's usage is as follows, using descriptions for each parameter. -`::nFormat:format:spaces:unitType:hex:hex2:debug` +`::nFormat:format:spaces:unitType:hex:hex2:debug:player=` - **nFormat**: the keyword to identify this attribute. - **format**: formatting based upon Java's DecimalFormat class. - **Required.** Defaults to #,##0.00. + **Required.** Defaults to #,##0.00. Examples of + how the formatting can be used: * #,### * #,###.00 * #,###.00000 @@ -334,7 +351,7 @@ Example of this attribute's usage is as follows, using descriptions for each par KB, MB, GB, TB, PB, EB, ZB, and YB. * *Note:* Other unitTypes can be added along with different style of - reducers. + reducers. Contact support for these requests. - **hex**: **Optional.** Case sensitive. Non-positional; can be placed anywhere. Only valid value is "hex". When enabled it will translate @@ -352,7 +369,10 @@ Example of this attribute's usage is as follows, using descriptions for each par will log to the console the status of this attribute, along with any error messages that may occur when applying the attribute. - +- **player=**: **Optional.** Case insensitive. Non-positional; can be + placed anywhere. If provided, it will try to use the specified + player as the primary player for the placeholder. If the current + user is provided, then this parameter may be ignored. @@ -385,7 +405,7 @@ The bar placeholder attribute only works with placeholders with the word bar in Example of this attribute's usage is as follows, using descriptions for each parameter. -`::bar:size:posColor:posSeg:negColor:negSeg:reverse:hex:hex2:debug` +`::bar:size:posColor:posSeg:negColor:negSeg:reverse:hex:hex2:debug:player=` @@ -420,6 +440,11 @@ Example of this attribute's usage is as follows, using descriptions for each par Only valid value is "debug". When enabled it will log to the console the status of this attribute, along with any error messages that may occur when applying the attribute. + +- **player=**: **Optional.** Case insensitive. Non-positional; can be + placed anywhere. If provided, it will try to use the specified + player as the primary player for the placeholder. If the current + user is provided, then this parameter may be ignored. @@ -464,7 +489,7 @@ placeholders. Example of this attribute's usage is as follows, using descriptions for each parameter. -`::text:hex:hex2:debug` +`::text:hex:hex2:debug:player=` @@ -483,6 +508,11 @@ Example of this attribute's usage is as follows, using descriptions for each par Only valid value is "debug". When enabled it will log to the console the status of this attribute, along with any error messages that may occur when applying the attribute. + +- **player=**: **Optional.** Case insensitive. Non-positional; can be + placed anywhere. If provided, it will try to use the specified + player as the primary player for the placeholder. If the current + user is provided, then this parameter may be ignored. diff --git a/prison-core/src/main/java/tech/mcprison/prison/placeholders/PlaceholderAttribute.java b/prison-core/src/main/java/tech/mcprison/prison/placeholders/PlaceholderAttribute.java index 8fdfd9137..264c7baaf 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/placeholders/PlaceholderAttribute.java +++ b/prison-core/src/main/java/tech/mcprison/prison/placeholders/PlaceholderAttribute.java @@ -4,4 +4,7 @@ public interface PlaceholderAttribute { public String format( String value ); + public String getPlayer(); + + public void setPlayer( String player ); } diff --git a/prison-core/src/main/java/tech/mcprison/prison/placeholders/PlaceholderAttributeBar.java b/prison-core/src/main/java/tech/mcprison/prison/placeholders/PlaceholderAttributeBar.java index 29e77c688..b3602f68d 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/placeholders/PlaceholderAttributeBar.java +++ b/prison-core/src/main/java/tech/mcprison/prison/placeholders/PlaceholderAttributeBar.java @@ -61,6 +61,8 @@ public class PlaceholderAttributeBar private boolean hex2 = false; private boolean debug = false; + private String player = null; + public PlaceholderAttributeBar(ArrayList parts, PlaceholderProgressBarConfig defaultBarConfig, String raw ) { super(); @@ -77,6 +79,22 @@ public PlaceholderAttributeBar(ArrayList parts, boolean isReversed = parts.remove( "reverse" ); + + // Search for 'player=': + for (String part : parts) { + if ( part.toLowerCase().startsWith( "player=" ) ) { + this.player = part; + break; + } + } + // extract the player's name: + if ( this.player != null ) { + if ( parts.remove( this.player ) ) { + this.player = this.player.toLowerCase().replaceAll("player=", ""); + } + } + + int len = 1; // format: @@ -184,6 +202,13 @@ public void setDebug( boolean debug ) { this.debug = debug; } + public String getPlayer() { + return player; + } + public void setPlayer(String player) { + this.player = player; + } + public PlaceholderProgressBarConfig getBarConfig() { return barConfig; } diff --git a/prison-core/src/main/java/tech/mcprison/prison/placeholders/PlaceholderAttributeNumberFormat.java b/prison-core/src/main/java/tech/mcprison/prison/placeholders/PlaceholderAttributeNumberFormat.java index 73c163e36..2427dca20 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/placeholders/PlaceholderAttributeNumberFormat.java +++ b/prison-core/src/main/java/tech/mcprison/prison/placeholders/PlaceholderAttributeNumberFormat.java @@ -86,6 +86,9 @@ public class PlaceholderAttributeNumberFormat private boolean hex2 = false; private boolean debug = false; + private String player = null; + + public PlaceholderAttributeNumberFormat( ArrayList parts, String raw ) { super(); @@ -99,6 +102,21 @@ public PlaceholderAttributeNumberFormat( ArrayList parts, String raw ) { this.hex2 = parts.remove( "hex2" ); this.debug = parts.remove( "debug" ); + // Search for 'player=': + for (String part : parts) { + if ( part.toLowerCase().startsWith( "player=" ) ) { + this.player = part; + break; + } + } + // extract the player's name: + if ( this.player != null ) { + if ( parts.remove( this.player ) ) { + this.player = this.player.toLowerCase().replaceAll("player=", ""); + } + } + + int len = 1; // format: @@ -310,4 +328,11 @@ public void setDebug( boolean debug ) { this.debug = debug; } + public String getPlayer() { + return player; + } + public void setPlayer(String player) { + this.player = player; + } + } diff --git a/prison-core/src/main/java/tech/mcprison/prison/placeholders/PlaceholderAttributeText.java b/prison-core/src/main/java/tech/mcprison/prison/placeholders/PlaceholderAttributeText.java index 919493408..456b0f81c 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/placeholders/PlaceholderAttributeText.java +++ b/prison-core/src/main/java/tech/mcprison/prison/placeholders/PlaceholderAttributeText.java @@ -52,6 +52,8 @@ public class PlaceholderAttributeText private boolean hex2 = false; private boolean debug = false; + private String player = null; + public PlaceholderAttributeText( ArrayList parts, String raw ) { super(); @@ -65,6 +67,22 @@ public PlaceholderAttributeText( ArrayList parts, String raw ) { this.hex2 = parts.remove( "hex2" ); this.debug = parts.remove( "debug" ); + + // Search for 'player=': + for (String part : parts) { + if ( part.toLowerCase().startsWith( "player=" ) ) { + this.player = part; + break; + } + } + // extract the player's name: + if ( this.player != null ) { + if ( parts.remove( this.player ) ) { + this.player = this.player.toLowerCase().replaceAll("player=", ""); + } + } + + } @@ -132,5 +150,11 @@ public void setDebug( boolean debug ) { this.debug = debug; } + public String getPlayer() { + return player; + } + public void setPlayer(String player) { + this.player = player; + } } diff --git a/prison-core/src/main/java/tech/mcprison/prison/placeholders/PlaceholderIdentifier.java b/prison-core/src/main/java/tech/mcprison/prison/placeholders/PlaceholderIdentifier.java index 1d48eee65..0d611bd37 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/placeholders/PlaceholderIdentifier.java +++ b/prison-core/src/main/java/tech/mcprison/prison/placeholders/PlaceholderIdentifier.java @@ -167,6 +167,14 @@ public boolean checkPlaceholderKey(PlaceHolderKey placeHolderKey) { return results; } + /** + *

Set the player's object, based upon the player's name, or based upon the + * placeholder attribute if a player attribute is provided. + *

+ * + * @param playerUuid + * @param playerName + */ public void setPlayer( UUID playerUuid, String playerName ) { Player player = null; @@ -194,6 +202,28 @@ public void setPlayer( UUID playerUuid, String playerName ) { if ( player != null ) { setPlayer(player); } + else { + // Check placeholder attributes for a defined player's namme: + String pName = getPlayerNameFromPlaceholderAttributes(); + + if ( pName != null ) { + + setPlayer( null, pName ); + } + } + } + + public String getPlayerNameFromPlaceholderAttributes() { + String player = null; + + for (PlaceholderAttribute phAttr : getAttributes() ) { + if ( phAttr.getPlayer() != null ) { + player = phAttr.getPlayer(); + break; + } + } + + return player; } public PlaceholderAttributeBar getAttributeBar() { diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/placeholder/SpigotPlaceholders.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/placeholder/SpigotPlaceholders.java index f6d4cc99c..ab0d2c206 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/placeholder/SpigotPlaceholders.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/placeholder/SpigotPlaceholders.java @@ -203,7 +203,7 @@ public int getPlaceholderRegistrationCount() { /** *

Provides placeholder translation for any placeholder identifier - * that is provided. This not the full text with one or more placeholders, + * that is provided. This not for full text with one or more placeholders, * but it is strictly just the placeholder. *

* From 79bb43254d770c9dab3407b081cd11dc284c4337 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sun, 1 Oct 2023 22:23:46 -0400 Subject: [PATCH 127/151] Update placeholder docs since github is showing the characters differently. --- docs/prison_docs_310_guide_placeholders.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/prison_docs_310_guide_placeholders.md b/docs/prison_docs_310_guide_placeholders.md index 688457d92..0dd29d5ca 100644 --- a/docs/prison_docs_310_guide_placeholders.md +++ b/docs/prison_docs_310_guide_placeholders.md @@ -252,7 +252,7 @@ Placeholders within prison can now be dynamically customized without having to m The **Placeholder Attributes** is additional text that is added at the end of a placeholder but within the escape characters. The placeholder attribute always begins with a double colon `::` and each parameter is separated with a single colon `:`. Some placeholders cannot use the attributes, and not all attributes can be used on a placeholder. See additional information below that pertains to each attribute. -**Player based placeholders** require player based requests that includes the player. Plugins that provide player based context would be like chat prefixes, scoreboards, and other placeholder consumers that need to use the player based placeholders. Some examples of placeholder consumers that will not have player based contexts, are with scoreboards and some script environments; these requests for player based placeholders would normally fail under regular conditions. To use player based placeholders with plugins that cannot support the player, you can solve this issue with the use of placeholder attributes with the **player=** attribute. See notes below on all placeholder attribute types. +**Player based placeholders** require player based requests that includes the player. Plugins that provide player based context would be like chat prefixes, scoreboards, and other placeholder consumers that need to use the player based placeholders. Some examples of placeholder consumers that will not have player based contexts, are with scoreboards and some script environments; these requests for player based placeholders would normally fail under regular conditions. To use player based placeholders with plugins that cannot support the player, you can solve this issue with the use of placeholder attributes with the **player=<playerName>** attribute. See notes below on all placeholder attribute types. As of v3.3.0-alpha.11h one placeholder can have more than one Placeholder Attribute, but they have to be of a different type. At this time, this really is not beneficial since the Placeholder Attributes are specific to a certain type of data. But this opens the door to future possibilities that are not possible currently, such as hybrid between a bar graph with a value super-imposed on top of it. @@ -369,7 +369,7 @@ Example of this attribute's usage is as follows, using descriptions for each par will log to the console the status of this attribute, along with any error messages that may occur when applying the attribute. -- **player=**: **Optional.** Case insensitive. Non-positional; can be +- **player=<playerName>**: **Optional.** Case insensitive. Non-positional; can be placed anywhere. If provided, it will try to use the specified player as the primary player for the placeholder. If the current user is provided, then this parameter may be ignored. @@ -441,7 +441,7 @@ Example of this attribute's usage is as follows, using descriptions for each par will log to the console the status of this attribute, along with any error messages that may occur when applying the attribute. -- **player=**: **Optional.** Case insensitive. Non-positional; can be +- **player=<playerName>**: **Optional.** Case insensitive. Non-positional; can be placed anywhere. If provided, it will try to use the specified player as the primary player for the placeholder. If the current user is provided, then this parameter may be ignored. @@ -509,7 +509,7 @@ Example of this attribute's usage is as follows, using descriptions for each par will log to the console the status of this attribute, along with any error messages that may occur when applying the attribute. -- **player=**: **Optional.** Case insensitive. Non-positional; can be +- **player=<playerName>**: **Optional.** Case insensitive. Non-positional; can be placed anywhere. If provided, it will try to use the specified player as the primary player for the placeholder. If the current user is provided, then this parameter may be ignored. From c3aa82d16bb6449db27198069539b606efc1b3d2 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Tue, 3 Oct 2023 09:21:33 -0400 Subject: [PATCH 128/151] Prison version: Improve the content of the auto features details. --- docs/changelog_v3.3.x.md | 5 +- .../prison/spigot/SpigotPlatform.java | 243 +++++++++++++----- 2 files changed, 176 insertions(+), 72 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 0cc379e08..6bf392ffb 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -14,7 +14,10 @@ These change logs represent the work that has been going on within prison. -# 3.3.0-alpha.15f 2023-10-01 +# 3.3.0-alpha.15f 2023-10-03 + + +* **Prison version: Improve the content of the auto features details.** * **Placeholders: Added the ability to specify a player name in all placeholder attributes.** diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/SpigotPlatform.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/SpigotPlatform.java index 3e32a1bae..a263f8f33 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/SpigotPlatform.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/SpigotPlatform.java @@ -2132,6 +2132,9 @@ public List getActiveFeatures( boolean showLaddersAndRanks ) { results.add( " " ); } + else { + results.add( "&7Ranks: &9Not Enabled." ); + } } @@ -2165,6 +2168,9 @@ public List getActiveFeatures( boolean showLaddersAndRanks ) { results.add( mineDetails ); } + else { + results.add( "&7Mines: &9Not Enabled." ); + } @@ -2179,7 +2185,13 @@ public List getActiveFeatures( boolean showLaddersAndRanks ) { boolean isAutoManagerEnabled = afw.isBoolean( AutoFeatures.isAutoManagerEnabled ); - results.add( String.format("AutoManager Enabled:&b %s", isAutoManagerEnabled) ); + + String autoMangerHeader = "&7AutoManager: " + + ( isAutoManagerEnabled ? + "&9Enabled" : + "&9Not Enabled" ); + + results.add( autoMangerHeader ); if ( isAutoManagerEnabled ) { @@ -2200,78 +2212,98 @@ public List getActiveFeatures( boolean showLaddersAndRanks ) { Boolean.toString( bbeCabebd ) ) ); + + results.add( formatAFEvent( "'&7org.bukkit.BlockBreakEvent&3'", AutoFeatures.blockBreakEventPriority ) ); + results.add( formatAFEvent( "Prison's own '&7ExplosiveBlockBreakEvent&3'", AutoFeatures.ProcessPrisons_ExplosiveBlockBreakEventsPriority ) ); + results.add( formatAFEvent( "Pulsi_'s PrisonEnchants '&7PEExplosiveEvent&3'", AutoFeatures.PrisonEnchantsExplosiveEventPriority ) ); + results.add( formatAFEvent( "TokenEnchant '&7BlockExplodeEvent&3'", AutoFeatures.TokenEnchantBlockExplodeEventPriority ) ); + + results.add( formatAFEvent( "CrazyEnchant '&7BlastUseEvent&3'", AutoFeatures.CrazyEnchantsBlastUseEventPriority ) ); + results.add( formatAFEvent( "RevEnchant '&7ExplosiveEvent&3'", AutoFeatures.RevEnchantsExplosiveEventPriority ) ); + results.add( formatAFEvent( "RevEnchant '&7JackHammerEvent&3'", AutoFeatures.RevEnchantsJackHammerEventPriority ) ); + results.add( formatAFEvent( "Zenchantments '&7BlockShredEvent&3'", AutoFeatures.ZenchantmentsBlockShredEventPriority ) ); + + results.add( formatAFEvent( "XPrison '&7ExplosionTriggerEvent&3'", AutoFeatures.XPrisonExplosionTriggerEventPriority ) ); + results.add( formatAFEvent( "XPrison '&7LayerTriggerEvent&3'", AutoFeatures.XPrisonLayerTriggerEventPriority ) ); + results.add( formatAFEvent( "XPrison '&7NukeTriggerEvent&3'", AutoFeatures.XPrisonNukeTriggerEventPriority ) ); + + - - String bbePriority = afw.getMessage( AutoFeatures.blockBreakEventPriority ); - BlockBreakPriority blockBreakPriority = BlockBreakPriority.fromString( bbePriority ); - results.add( String.format(". '&7org.bukkit.BlockBreakEvent&3' Priority:&b %s", - blockBreakPriority.name() ) ); - - String pebbePriority = afw.getMessage( AutoFeatures.ProcessPrisons_ExplosiveBlockBreakEventsPriority ); - boolean isPebbeEnabled = pebbePriority != null && !"DISABLED".equalsIgnoreCase( pebbePriority ); - BlockBreakPriority pebbeEventPriority = BlockBreakPriority.fromString( pebbePriority ); - results.add( String.format("%s. Prison's own '&7ExplosiveBlockBreakEvent&3' Priority:&b %s %s", - (isPebbeEnabled ? "" : "+" ), - pebbeEventPriority.name(), - (isPebbeEnabled ? "&2Enabled" : "&cDisabled") - ) ); +// String bbePriority = afw.getMessage( AutoFeatures.blockBreakEventPriority ); +// BlockBreakPriority blockBreakPriority = BlockBreakPriority.fromString( bbePriority ); +// results.add( String.format(". '&7org.bukkit.BlockBreakEvent&3' Priority:&b %s", +// blockBreakPriority.name() ) ); - String peeePriority = afw.getMessage( AutoFeatures.PrisonEnchantsExplosiveEventPriority ); - boolean isPeeeEnabled = peeePriority != null && !"DISABLED".equalsIgnoreCase( peeePriority ); - BlockBreakPriority peeeEventPriority = BlockBreakPriority.fromString( peeePriority ); - results.add( String.format("%s. Pulsi_'s PrisonEnchants '&7PEExplosiveEvent&3' Priority:&b %s %s", - (isPeeeEnabled ? "" : "+" ), - peeeEventPriority.name(), - (isPeeeEnabled ? "&2Enabled" : "&cDisabled") - ) ); +// String pebbePriority = afw.getMessage( AutoFeatures.ProcessPrisons_ExplosiveBlockBreakEventsPriority ); +// boolean isPebbeEnabled = pebbePriority != null && !"DISABLED".equalsIgnoreCase( pebbePriority ); +// BlockBreakPriority pebbeEventPriority = BlockBreakPriority.fromString( pebbePriority ); +// results.add( String.format("%s. Prison's own '&7ExplosiveBlockBreakEvent&3' Priority:&b %s %s", +// (isPebbeEnabled ? "" : "+" ), +// pebbeEventPriority.name(), +// (isPebbeEnabled ? "&2Enabled" : "&cDisabled") +// ) ); - String tebePriority = afw.getMessage( AutoFeatures.TokenEnchantBlockExplodeEventPriority ); - boolean isTebeEnabled = tebePriority != null && !"DISABLED".equalsIgnoreCase( tebePriority ); - BlockBreakPriority tebEventPriority = BlockBreakPriority.fromString( tebePriority ); - results.add( String.format("%s. TokenEnchant '&7BlockExplodeEvent&3' Priority:&b %s %s", - (isTebeEnabled ? "" : "+" ), - tebEventPriority.name(), - (isTebeEnabled ? "&2Enabled" : "&cDisabled") - ) ); +// String peeePriority = afw.getMessage( AutoFeatures.PrisonEnchantsExplosiveEventPriority ); +// boolean isPeeeEnabled = peeePriority != null && !"DISABLED".equalsIgnoreCase( peeePriority ); +// BlockBreakPriority peeeEventPriority = BlockBreakPriority.fromString( peeePriority ); +// results.add( String.format("%s. Pulsi_'s PrisonEnchants '&7PEExplosiveEvent&3' Priority:&b %s %s", +// (isPeeeEnabled ? "" : "+" ), +// peeeEventPriority.name(), +// (isPeeeEnabled ? "&2Enabled" : "&cDisabled") +// ) ); +// +// String tebePriority = afw.getMessage( AutoFeatures.TokenEnchantBlockExplodeEventPriority ); +// boolean isTebeEnabled = tebePriority != null && !"DISABLED".equalsIgnoreCase( tebePriority ); +// BlockBreakPriority tebEventPriority = BlockBreakPriority.fromString( tebePriority ); +// results.add( String.format("%s. TokenEnchant '&7BlockExplodeEvent&3' Priority:&b %s %s", +// (isTebeEnabled ? "" : "+" ), +// tebEventPriority.name(), +// (isTebeEnabled ? "&2Enabled" : "&cDisabled") +// ) ); - String reeePriority = afw.getMessage( AutoFeatures.RevEnchantsExplosiveEventPriority ); - boolean isReeeEnabled = reeePriority != null && !"DISABLED".equalsIgnoreCase( reeePriority ); - BlockBreakPriority reeEventPriority = BlockBreakPriority.fromString( reeePriority ); - results.add( String.format("%s. RevEnchant '&7ExplosiveEvent&3' Priority:&b %s %s", - (isReeeEnabled ? "" : "+" ), - reeEventPriority.name(), - (isReeeEnabled ? "&2Enabled" : "&cDisabled") - ) ); - String rejhePriority = afw.getMessage( AutoFeatures.RevEnchantsJackHammerEventPriority ); - boolean isRejheEnabled = rejhePriority != null && !"DISABLED".equalsIgnoreCase( rejhePriority ); - BlockBreakPriority rejhEventPriority = BlockBreakPriority.fromString( rejhePriority ); - results.add( String.format("%s. RevEnchant '&7JackHammerEvent&3' Priority:&b %s %s", - (isRejheEnabled ? "" : "+" ), - rejhEventPriority.name(), - (isRejheEnabled ? "&2Enabled" : "&cDisabled") - ) ); +// String reeePriority = afw.getMessage( AutoFeatures.RevEnchantsExplosiveEventPriority ); +// boolean isReeeEnabled = reeePriority != null && !"DISABLED".equalsIgnoreCase( reeePriority ); +// BlockBreakPriority reeEventPriority = BlockBreakPriority.fromString( reeePriority ); +// results.add( String.format("%s. RevEnchant '&7ExplosiveEvent&3' Priority:&b %s %s", +// (isReeeEnabled ? "" : "+" ), +// reeEventPriority.name(), +// (isReeeEnabled ? "&2Enabled" : "&cDisabled") +// ) ); +// +// String rejhePriority = afw.getMessage( AutoFeatures.RevEnchantsJackHammerEventPriority ); +// boolean isRejheEnabled = rejhePriority != null && !"DISABLED".equalsIgnoreCase( rejhePriority ); +// BlockBreakPriority rejhEventPriority = BlockBreakPriority.fromString( rejhePriority ); +// results.add( String.format("%s. RevEnchant '&7JackHammerEvent&3' Priority:&b %s %s", +// (isRejheEnabled ? "" : "+" ), +// rejhEventPriority.name(), +// (isRejheEnabled ? "&2Enabled" : "&cDisabled") +// ) ); - String cebuePriority = afw.getMessage( AutoFeatures.CrazyEnchantsBlastUseEventPriority ); - boolean isCebueEnabled = cebuePriority != null && !"DISABLED".equalsIgnoreCase( cebuePriority ); - BlockBreakPriority cebuEventPriority = BlockBreakPriority.fromString( cebuePriority ); - results.add( String.format("%s. CrazyEnchant '&7BlastUseEvent&3' Priority:&b %s %s", - (isCebueEnabled ? "" : "+" ), - cebuEventPriority.name(), - (isCebueEnabled ? "&2Enabled" : "&cDisabled") - ) ); - - String zbsePriority = afw.getMessage( AutoFeatures.ZenchantmentsBlockShredEventPriority ); - boolean isZbseEnabled = zbsePriority != null && !"DISABLED".equalsIgnoreCase( zbsePriority ); - BlockBreakPriority zbsEventPriority = BlockBreakPriority.fromString( zbsePriority ); - results.add( String.format("%s. Zenchantments '&7BlockShredEvent&3' Priority:&b %s %s", - (isZbseEnabled ? "" : "+" ), - zbsEventPriority.name(), - (isZbseEnabled ? "&2Enabled" : "&cDisabled") - ) ); +// String cebuePriority = afw.getMessage( AutoFeatures.CrazyEnchantsBlastUseEventPriority ); +// boolean isCebueEnabled = cebuePriority != null && !"DISABLED".equalsIgnoreCase( cebuePriority ); +// BlockBreakPriority cebuEventPriority = BlockBreakPriority.fromString( cebuePriority ); +// results.add( String.format("%s. CrazyEnchant '&7BlastUseEvent&3' Priority:&b %s %s", +// (isCebueEnabled ? "" : "+" ), +// cebuEventPriority.name(), +// (isCebueEnabled ? "&2Enabled" : "&cDisabled") +// ) ); +// +// String zbsePriority = afw.getMessage( AutoFeatures.ZenchantmentsBlockShredEventPriority ); +// boolean isZbseEnabled = zbsePriority != null && !"DISABLED".equalsIgnoreCase( zbsePriority ); +// BlockBreakPriority zbsEventPriority = BlockBreakPriority.fromString( zbsePriority ); +// results.add( String.format("%s. Zenchantments '&7BlockShredEvent&3' Priority:&b %s %s", +// (isZbseEnabled ? "" : "+" ), +// zbsEventPriority.name(), +// (isZbseEnabled ? "&2Enabled" : "&cDisabled") +// ) ); + + + + // String peeePriority = afw.getMessage( AutoFeatures.PrisonEnchantsExplosiveEventPriority ); // boolean isPeeeeEnabled = afw.isBoolean( AutoFeatures.isProcessPrisonEnchantsExplosiveEvents ); // BlockBreakPriority peeEventPriority = BlockBreakPriority.fromString( peeePriority ); @@ -2323,13 +2355,34 @@ public List getActiveFeatures( boolean showLaddersAndRanks ) { (isDurabilityEnabled ? "" : "+"), isDurabilityEnabled) ); + boolean isPreventToolBreakage = afw.isBoolean( AutoFeatures.isPreventToolBreakage ); + results.add( String.format("%s. Prevent Tool Breakage:&b %s", + (isPreventToolBreakage ? "" : "+"), + isPreventToolBreakage) ); + + results.add( String.format("%s. Prevent Tool Breakage Threshold:&b %s", + (isPreventToolBreakage ? "" : "+"), + afw.getInteger( AutoFeatures.preventToolBreakageThreshold )) ); + + + + boolean isCalcFortune = afw.isBoolean( AutoFeatures.isCalculateFortuneEnabled ); + results.add( String.format(". Calculate Fortune:&b %s", isCalcFortune) ); - results.add( String.format("+. . Fortune Multiplier:&b %s", + + boolean isUseTEFortuneLevel = afw.isBoolean( AutoFeatures.isUseTokenEnchantsFortuneLevel ); + results.add( String.format("%s. . Use TokenEnchants Fortune Level:&b %b", + (isUseTEFortuneLevel ? "" : "+"), + isUseTEFortuneLevel) ); + + results.add( String.format("+. . Fortune Multiplier Global:&b %s", afw.getInteger( AutoFeatures.fortuneMultiplierGlobal )) ); results.add( String.format("+. . Max Fortune Level:&b %s &3(0 = no max Level)", afw.getInteger( AutoFeatures.fortuneMultiplierMax )) ); + results.add( String.format("+. . Fortune Bukkit Drops Multiplier:&b %s &3", + afw.getDouble( AutoFeatures.fortuneBukkitDropsMultiplier )) ); boolean isExtendedBukkitFortune = afw.isBoolean( AutoFeatures.isExtendBukkitFortuneCalculationsEnabled ); results.add( String.format(". . Extended Bukkit Fortune Enabled:&b %s", @@ -2341,17 +2394,46 @@ public List getActiveFeatures( boolean showLaddersAndRanks ) { afw.getInteger( AutoFeatures.extendBukkitFortuneFactorPercentRangeHigh )) ); + boolean isAltFortune = afw.isBoolean( AutoFeatures.isCalculateAltFortuneEnabled); results.add( "+&3NOTE: If you enable Extended Bukkit Fortune, then it auto disables the following Alt Fortune Cals." ); results.add( "+&3NOTE: First try Extended Bukkit Fortune and if it does not work, then disable it and use " + "Alt Fortune." ); - results.add( String.format("%s. . Calculate Alt Fortune Enabled:&b %s %s", + results.add( String.format("%s. . Calculate Alt Fortune Enabled:&b %s", (isExtendedBukkitFortune ? "+" : "" ), - ( afw.isBoolean( AutoFeatures.isCalculateAltFortuneEnabled) ? "&2Enabled" : "&cDisabled"), - ( isExtendedBukkitFortune ? "&d[disabled by Exended Bukkit Fortune]" : "")) ); - results.add( String.format("%s. . Calculate Alt Fortune on all Blocks:&b %s %s", + ( isAltFortune ? "&2Enabled" : "&cDisabled") + ) ); + results.add( String.format("%s. . Calculate Alt Fortune on all Blocks:&b %s", (isExtendedBukkitFortune ? "+" : "" ), - ( afw.isBoolean( AutoFeatures.isCalculateAltFortuneOnAllBlocksEnabled) ? "&2Enabled" : "&cDisabled"), - ( isExtendedBukkitFortune ? "&d[disabled by Exended Bukkit Fortune]" : "")) ); + ( afw.isBoolean( AutoFeatures.isCalculateAltFortuneOnAllBlocksEnabled) ? "&2Enabled" : "&cDisabled") + ) ); + if ( isAltFortune && isExtendedBukkitFortune ) { + results.add( "&dWarning: Alt Fortune is disabled by Exended Bukkit Fortune." ); + } + + + boolean isGradientFortune = afw.isBoolean( AutoFeatures.isPercentGradientFortuneEnabled ); + + results.add( String.format("%s. Percent Gradient Fortune Enabled:&b %s", + (isGradientFortune ? "" : "+"), + isGradientFortune ) ); + + if ( isGradientFortune ) { + + if ( isExtendedBukkitFortune ) { + results.add( "&dWarning: Percent Gradient Fortune is disabled by Exended Bukkit Fortune." ); + } + if ( isAltFortune ) { + results.add( "&dWarning: Percent Gradient Fortune is disabled by Alt Fortune." ); + } + + results.add( String.format(". . Percent Gradient Fortune: Max Fortune Level:&b %s", + afw.getInteger( AutoFeatures.percentGradientFortuneMaxFortuneLevel )) ); + results.add( String.format(". . Percent Gradient Fortune: Max Bonus Blocks: &b %s", + afw.getInteger( AutoFeatures.percentGradientFortuneMaxBonusBlocks )) ); + results.add( String.format(". . Percent Gradient Fortune: Min Percent Randomness: &b%s", + afw.getDouble( AutoFeatures.percentGradientFortuneMinPercentRandomness )) ); + + } results.add( " " ); @@ -2417,6 +2499,25 @@ public List getActiveFeatures( boolean showLaddersAndRanks ) { } + private String formatAFEvent(String description, AutoFeatures autoFeature ) { + String results = null; + + String ePriority = AutoFeaturesWrapper.getInstance().getMessage( autoFeature ); + + BlockBreakPriority eventPriority = BlockBreakPriority.fromString( ePriority ); + + boolean isEnabled = eventPriority != BlockBreakPriority.DISABLED; + + results = String.format("%s. %s Priority:&b %s %s", + (isEnabled ? "" : "+" ), + description, + eventPriority.name(), + (isEnabled ? "&2Enabled" : "&cDisabled") + ); + + return results; + } + @Override public void prisonVersionFeatures( ChatDisplay display, boolean isBasic, boolean showLaddersAndRanks ) { From dcedf89a25e555156c7e1dc34f26386ce8517988 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Tue, 3 Oct 2023 09:23:34 -0400 Subject: [PATCH 129/151] Player Economy Cache Delay: Add the ability to change the player economy cache delay. Default value is 3 seconds, or 60 ticks. --- docs/changelog_v3.3.x.md | 3 ++ .../prison/spigot/sellall/SellAllUtil.java | 50 +++++++++++++++++-- prison-spigot/src/main/resources/config.yml | 16 ++++++ 3 files changed, 64 insertions(+), 5 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 6bf392ffb..aa8707b8f 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -17,6 +17,9 @@ These change logs represent the work that has been going on within prison. # 3.3.0-alpha.15f 2023-10-03 +* **Player Economy Cache Delay: Add the ability to change the player economy cache delay. Default value is 3 seconds, or 60 ticks.** + + * **Prison version: Improve the content of the auto features details.** diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/sellall/SellAllUtil.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/sellall/SellAllUtil.java index e38bfcfd2..1acf5a8eb 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/sellall/SellAllUtil.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/sellall/SellAllUtil.java @@ -100,6 +100,8 @@ public class SellAllUtil public boolean isSellAllSignNotifyEnabled; public boolean isSellAllSignPermissionToUseEnabled; public boolean isSellAllNotificationEnabled; + public boolean isSellAllNotificationByActionBar; + public boolean isSellAllSoundEnabled; public boolean isSellAllBackpackItemsEnabled; public boolean isSellAllMinesBackpacksPluginEnabled; @@ -157,10 +159,13 @@ private void initCachedData() { isAutoSellPerUserToggleable = getBooleanValue("Options.Full_Inv_AutoSell_perUserToggleable"); isAutoSellPerUserToggleablePermEnabled = getBooleanValue("Options.Full_Inv_AutoSell_perUserToggleable_Need_Perm"); isSellAllNotificationEnabled = getBooleanValue("Options.Sell_Notify_Enabled"); + isSellAllNotificationByActionBar = getBooleanValue("Options.Sell_Notify_by_ActionBar"); + isSellAllSoundEnabled = getBooleanValue("Options.Sell_Sound_Enabled"); isSellAllBackpackItemsEnabled = getBooleanValue("Options.Sell_Prison_BackPack_Items"); isSellAllMinesBackpacksPluginEnabled = getBooleanValue("Options.Sell_MinesBackPacks_Plugin_Backpack"); isSellAllDelayEnabled = getBooleanValue("Options.Sell_Delay_Enabled"); + isSellAllSellPermissionEnabled = getBooleanValue("Options.Sell_Permission_Enabled"); isSellAllItemTriggerEnabled = getBooleanValue("Options.ShiftAndRightClickSellAll.Enabled"); isSellAllItemTriggerPermissionEnabled = getBooleanValue("Options.ShiftAndRightClickSellAll.PermissionEnabled"); @@ -1460,7 +1465,9 @@ public boolean addToAutoSellNotificationDelay(Player p){ if (!isPlayerWaitingAutoSellNotification(p)){ autoSellEarningsNotificationWaiting.put(p, 0.00); - Bukkit.getScheduler().scheduleSyncDelayedTask(SpigotPrison.getInstance(), () -> removeFromAutoSellDelayAndNotify(p), 20L * defaultAutoSellEarningNotificationDelay); + Bukkit.getScheduler().scheduleSyncDelayedTask( + SpigotPrison.getInstance(), + () -> removeFromAutoSellDelayAndNotify(p), 20L * defaultAutoSellEarningNotificationDelay); return true; } @@ -2062,9 +2069,19 @@ public void removeFromAutoSellDelayAndNotify(Player p){ String message = sellallAmountEarnedMsg( amt ); + SpigotPlayer sPlayer = new SpigotPlayer(p); + + if ( isSellAllNotificationByActionBar ) { + + sPlayer.setActionBar( message ); + } + else { + + Output.get().send( sPlayer, message ); + } + // String message = messages.getString(MessagesConfig.StringID.spigot_message_sellall_money_earned) + amt; // new SpigotPlayer(p).setActionBar( message ); - Output.get().send( new SpigotPlayer(p), message ); } autoSellEarningsNotificationWaiting.remove(p); } @@ -2427,9 +2444,17 @@ else if (notifyPlayerEarned) { String message = sellallAmountEarnedMsg( amt ); + if ( isSellAllNotificationByActionBar ) { + sPlayer.setActionBar( message ); + } + else { + + Output.get().send( sPlayer, message ); + } + // String message = messages.getString(MessagesConfig.StringID.spigot_message_sellall_money_earned) + amt; // new SpigotPlayer(p).setActionBar( message ); - Output.get().send( new SpigotPlayer(p), message ); +// Output.get().send( sPlayer, message ); } } @@ -2529,9 +2554,17 @@ else if (notifyPlayerEarned){ String message = sellallAmountEarnedMsg( amt ) ; + if ( isSellAllNotificationByActionBar ) { + sPlayer.setActionBar( message ); + } + else { + + Output.get().send( sPlayer, message ); + } + // String message = messages.getString(MessagesConfig.StringID.spigot_message_sellall_money_earned) + amt; // new SpigotPlayer(p).setActionBar( message ); - Output.get().send( new SpigotPlayer(p), message ); +// Output.get().send( sPlayer, message ); } } @@ -2703,9 +2736,16 @@ public ArrayList sellAllSell(Player p, ArrayList itemStack String message = sellallAmountEarnedMsg( amt ); + if ( isSellAllNotificationByActionBar ) { + sPlayer.setActionBar( message ); + } + else { + + Output.get().send( sPlayer, message ); + } + // String message = messages.getString(MessagesConfig.StringID.spigot_message_sellall_money_earned) + amt; // new SpigotPlayer(p).setActionBar( message ); - Output.get().send( new SpigotPlayer(p), message ); } } diff --git a/prison-spigot/src/main/resources/config.yml b/prison-spigot/src/main/resources/config.yml index 73693345a..f32cdc58a 100644 --- a/prison-spigot/src/main/resources/config.yml +++ b/prison-spigot/src/main/resources/config.yml @@ -119,6 +119,21 @@ prestige: # all functions able to handle new players that have not been added to Prison due to # the degree of complexity of some sections of prison. # +# The 'player-economy-cache-update-delay-ticks' provides the nummber of ticks of a delay +# from when a player is paid money, until the prison updates the econommy. The default +# delay is 3 seconds, or 60 tickks. The purpose of this delayed update is to prevent the +# frequent player payments while speed-mining fromm overwhelming the economy plugin. +# For example, if there are 20 players online, all mining with a highly efficent pickaxe, +# and with autosell enabled, a single player would recieve payments for each block broken, +# of which could quickly exceed 20 to 40 updates per second per player. So with 20 players +# mining concurrently, the econommy plugin would have to be able to handle 400, to 800 +# updates per second, if not more. Some economy plugins cannot handle such loads, and +# can cause the server to lag becaus they are not using asynchronous updates to the storage +# of choice, and they mmay not cache the updates to prevent so many updates. +# If the 3 second delay is too long, and you're wanting something a little quicker, try +# reducing the number of ticks to like 30, 20, or 10. Becareful of going too low. If +# you notice potential server deplays, trying incrasing the delays. You can use +# `/timings` to confirm where the lag is occuring. ranks: startup: @@ -126,6 +141,7 @@ ranks: gui-default-include-rankup-button: true gui-prestiges-include-rankup-button: true gui-others-include-rankup-button: true + player-economy-cache-update-delay-ticks: 60 From 91ac31cc5096c6f332a9344eb2aff25804aea673 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sun, 8 Oct 2023 02:23:32 -0400 Subject: [PATCH 130/151] v3.3.0-alpha.15g 2023-10-03 --- docs/changelog_v3.3.x.md | 6 +++++- gradle.properties | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index aa8707b8f..23859975c 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -14,7 +14,11 @@ These change logs represent the work that has been going on within prison. -# 3.3.0-alpha.15f 2023-10-03 +# 3.3.0-alpha.15g 2023-10-03 + + + +**v3.3.0-alpha.15g 2023-10-03** * **Player Economy Cache Delay: Add the ability to change the player economy cache delay. Default value is 3 seconds, or 60 ticks.** diff --git a/gradle.properties b/gradle.properties index f5304a428..3f422f4d5 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,7 +3,7 @@ ## # This is actually the "correct" place to define the version for the project. ## # Used within build.gradle with ${project.version}. ## # Can be overridden on the command line: gradle -Pversion=3.2.1-alpha.3 -version=3.3.0-alpha.15f +version=3.3.0-alpha.15g From 817e2c25231385f479a138f1e7c64f92885a69b9 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sun, 8 Oct 2023 02:27:09 -0400 Subject: [PATCH 131/151] *Bug: sellall auto sell enabled messages reversed. The command to enable and disable the auto sell feature was reversed, so when turning off, it would report that it was just turned on. And on when it was turned off. --- docs/changelog_v3.3.x.md | 4 ++++ .../prison/spigot/commands/PrisonSpigotSellAllCommands.java | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 23859975c..8d43ba728 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -18,6 +18,10 @@ These change logs represent the work that has been going on within prison. +* **Bug: sellall auto enabled messages reversed.** +The command to enable and disable the auto sell feature was reversed, so when turning off, it would report that it was just turned on. And on when it was turned off. + + **v3.3.0-alpha.15g 2023-10-03** diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/commands/PrisonSpigotSellAllCommands.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/commands/PrisonSpigotSellAllCommands.java index a81943f1f..9856f1601 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/commands/PrisonSpigotSellAllCommands.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/commands/PrisonSpigotSellAllCommands.java @@ -623,9 +623,9 @@ private void sellAllAutoEnableUser(CommandSender sender){ boolean isplayerAutosellEnabled = sellAllUtil.isPlayerAutoSellEnabled(p); if (sellAllUtil.setAutoSellPlayer(p, !isplayerAutosellEnabled)){ if ( !isplayerAutosellEnabled ){ // Note this variable was negated then saved, so we need to check the negative: - Output.get().sendInfo(new SpigotPlayer(p), messages.getString(MessagesConfig.StringID.spigot_message_sellall_auto_enabled)); - } else { Output.get().sendInfo(new SpigotPlayer(p), messages.getString(MessagesConfig.StringID.spigot_message_sellall_auto_disabled)); + } else { + Output.get().sendInfo(new SpigotPlayer(p), messages.getString(MessagesConfig.StringID.spigot_message_sellall_auto_enabled)); } } } From 1018c83ccead5877345bf3ad6a240c689492549d Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sun, 8 Oct 2023 02:34:57 -0400 Subject: [PATCH 132/151] SellAll messages: Cleaned up some of the US EN messages related to the sellall command. --- docs/changelog_v3.3.x.md | 4 +++- .../resources/lang/spigot/en_US.properties | 22 +++++++++---------- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 8d43ba728..65a90ed0f 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -17,8 +17,10 @@ These change logs represent the work that has been going on within prison. # 3.3.0-alpha.15g 2023-10-03 +* **SellAll messages: Cleaned up some of the US EN messages related to the sellall command.** -* **Bug: sellall auto enabled messages reversed.** + +* **Bug: sellall auto sell enabled messages reversed.** The command to enable and disable the auto sell feature was reversed, so when turning off, it would report that it was just turned on. And on when it was turned off. diff --git a/prison-core/src/main/resources/lang/spigot/en_US.properties b/prison-core/src/main/resources/lang/spigot/en_US.properties index ba94bc37f..7207e9d4f 100644 --- a/prison-core/src/main/resources/lang/spigot/en_US.properties +++ b/prison-core/src/main/resources/lang/spigot/en_US.properties @@ -225,20 +225,20 @@ spigot_message_prestiges_cancelled_wrong_keyword=Prestige &ccancelled&7, you did ## Ranks Messages spigot_message_ranks_disabled=Sorry, Ranks are disabled. spigot_message_ranks_or_gui_disabled=Sorry, Ranks or GUIs are disabled. -spigot_message_ranks_tag_chat_rename_1=Please write the &6tag &7you'd like to use and &6submit&7. +spigot_message_ranks_tag_chat_rename_1=Please enter the &6tag &7you'd like to use and &6submit&7. spigot_message_ranks_tag_chat_rename_2=Input &cclose &7to cancel or wait &c30 seconds&7. -spigot_message_ranks_tag_chat_cancelled=Rename tag &cclosed&7, nothing got changed! +spigot_message_ranks_tag_chat_cancelled=Rename tag &cclosed&7, nothing was changed! ## SellAll Messages -spigot_message_sellall_auto_already_enabled=Sellall Auto already enabled. -spigot_message_sellall_auto_already_disabled=SellAll Auto already disabled. -spigot_message_sellall_auto_disabled=SellAll Auto disabled with success. +spigot_message_sellall_auto_already_enabled=Sellall AutoSell was already enabled. +spigot_message_sellall_auto_already_disabled=SellAll AutoSell wasg already disabled. +spigot_message_sellall_auto_disabled=AutoSell has been disabled. spigot_message_sellall_auto_disabled_cant_use=Sorry, you need to enable AutoSell to use this. -spigot_message_sellall_auto_enabled=SellAll Auto enabled with success. -spigot_message_sellall_auto_perusertoggleable_enabled=Sellall Auto perUserToggleable enabled with success. -spigot_message_sellall_auto_perusertoggleable_disabled=Sellall Auto perUserToggleable disabled with success. -spigot_message_sellall_auto_perusertoggleable_already_enabled=Sellall Auto perUserToggleable already enabled. -spigot_message_sellall_auto_perusertoggleable_already_disabled=Sellall Auto perUserToggleable already disabled. +spigot_message_sellall_auto_enabled=AutoSell has been enabled. +spigot_message_sellall_auto_perusertoggleable_enabled=Sellall AutoSell perUserToggleable is enabled. +spigot_message_sellall_auto_perusertoggleable_disabled=Sellall AutoSell perUserToggleable is disabled. +spigot_message_sellall_auto_perusertoggleable_already_enabled=Sellall AutoSell perUserToggleable already enabled. +spigot_message_sellall_auto_perusertoggleable_already_disabled=Sellall AutoSell perUserToggleable already disabled. spigot_message_sellall_boolean_input_invalid=The boolean value isn't valid (Valid values are True or False). spigot_message_sellall_cant_find_item_config=Sorry, can't find your item in the config. spigot_message_sellall_currency_chat_1=&3Started setup of new currency for SellAll! @@ -248,7 +248,7 @@ spigot_message_sellall_currency_chat_4=Type the &aCurrency name &7to set the new spigot_message_sellall_currency_edit_success=SellAll Currency edited with success. spigot_message_sellall_currency_not_found=Sorry, currency not found. spigot_message_sellall_hand_disabled=SellAll Hand disabled with success. -spigot_message_sellall_hand_enabled=Sellall Hand enabled with success. +spigot_message_sellall_hand_enabled=SellAll Hand enabled with success. spigot_message_sellall_hand_is_disabled=SellAll Hand is disabled. spigot_message_sellall_item_add_success=Item added with success. spigot_message_sellall_item_already_added=You've already added this item, please use the edit command instead. From f79a66e74fdc5aa7767148c4ea32f57185e5d539 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sun, 8 Oct 2023 02:38:25 -0400 Subject: [PATCH 133/151] Player Economy Cache Delay: Add the ability to change the player economy cache delay. Default value is 3 seconds, or 60 ticks. --- .../mcprison/prison/ranks/data/RankPlayer.java | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/prison-core/src/main/java/tech/mcprison/prison/ranks/data/RankPlayer.java b/prison-core/src/main/java/tech/mcprison/prison/ranks/data/RankPlayer.java index 6021ed64e..06af55f65 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/ranks/data/RankPlayer.java +++ b/prison-core/src/main/java/tech/mcprison/prison/ranks/data/RankPlayer.java @@ -114,6 +114,8 @@ public class RankPlayer // private double rankScoreBalanceThreshold = 0; // private long rankScoreCooldown = 0L; + + private long economyCacheUpdateDelayTicks = -1; public RankPlayer() { super(); @@ -1182,6 +1184,19 @@ public double getBalanceUnsaved() { return unsavedBalance; } + + public long getEconomyCacheUpdateDelayTicks() { + + if ( this.economyCacheUpdateDelayTicks == -1 ) { + + this.economyCacheUpdateDelayTicks = + Prison.get().getPlatform().getConfigLong( + "ranks.player-economy-cache-update-delay-ticks", DELAY_THREE_SECONDS ); + } + + return this.economyCacheUpdateDelayTicks; + } + public void addBalance( double amount ) { synchronized ( unsavedBalanceLock ) @@ -1202,7 +1217,7 @@ public void addBalance( double amount ) { unsavedBalance = 0; ubTaskId = 0; } - }, DELAY_THREE_SECONDS ); + }, getEconomyCacheUpdateDelayTicks() ); } } From 70b1f3eeadfc424edea93cbaa8aa7bf6dea2ce49 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sun, 8 Oct 2023 04:27:24 -0400 Subject: [PATCH 134/151] Placeholders: bug fix: If using the placeholder attribute for an off line player, it would cause an error when checking if the player was in a disabled world. --- docs/changelog_v3.3.x.md | 5 ++++- .../prison/spigot/placeholder/SpigotPlaceholders.java | 4 +++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 65a90ed0f..24b296aef 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -14,7 +14,10 @@ These change logs represent the work that has been going on within prison. -# 3.3.0-alpha.15g 2023-10-03 +# 3.3.0-alpha.15g 2023-10-08 + + +* **Placeholders: bug fix: If using the placeholder attribute for an off line player, it would cause an error when checking if the player was in a disabled world.** * **SellAll messages: Cleaned up some of the US EN messages related to the sellall command.** diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/placeholder/SpigotPlaceholders.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/placeholder/SpigotPlaceholders.java index ab0d2c206..72cb87a07 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/placeholder/SpigotPlaceholders.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/placeholder/SpigotPlaceholders.java @@ -459,7 +459,9 @@ private String replaceAllPlaceholders(UUID playerUuid, String playerName, String String replacementText = processPlaceholderIdentifier(identifier); if ( identifier.isFoundAMatch() ) { - if ( ignorePlayerInDisabledWorlds( (SpigotPlayer) identifier.getPlayer() )) { + if ( identifier.getPlayer() != null && + identifier.getPlayer() instanceof SpigotPlayer && + ignorePlayerInDisabledWorlds( (SpigotPlayer) identifier.getPlayer() )) { replacementText = ""; } From 420aca9c53befca842b2a9d51e32d81be12915f2 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sun, 8 Oct 2023 04:29:10 -0400 Subject: [PATCH 135/151] Placeholders: Added the ability to provide a shorted output of the command `/prison placeholders test` so it only shows the command header and the results. --- docs/changelog_v3.3.x.md | 4 +++ .../tech/mcprison/prison/PrisonCommand.java | 32 +++++++++++-------- 2 files changed, 23 insertions(+), 13 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 24b296aef..409e6b065 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -17,6 +17,10 @@ These change logs represent the work that has been going on within prison. # 3.3.0-alpha.15g 2023-10-08 +* **Placeholders: Added the ability to provide a shorted output of the command `/prison placeholders test` so it only shows the command header and the results.** + + + * **Placeholders: bug fix: If using the placeholder attribute for an off line player, it would cause an error when checking if the player was in a disabled world.** diff --git a/prison-core/src/main/java/tech/mcprison/prison/PrisonCommand.java b/prison-core/src/main/java/tech/mcprison/prison/PrisonCommand.java index 78eaa4ff4..ada535123 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/PrisonCommand.java +++ b/prison-core/src/main/java/tech/mcprison/prison/PrisonCommand.java @@ -538,7 +538,9 @@ public void troubleshootListCommand(CommandSender sender) { @Command(identifier = "prison placeholders test", - description = "Converts any Prison placeholders in the test string to their values", + description = "Converts any Prison placeholders in the test string to their values. " + + "Use '-s' keyword to reduce output text. " + + "All placeholder attributes are supported.", onlyPlayers = false, permissions = "prison.placeholder") public void placeholdersTestCommand(CommandSender sender, @Arg(name = "playerName", description = "Player name to use with player rank placeholders (optional)", @@ -576,6 +578,10 @@ public void placeholdersTestCommand(CommandSender sender, player = getPlayer( sender ); } + boolean isShort = text.startsWith( "-s " ); + if ( isShort ) { + text = text.substring( 3 ); + } ChatDisplay display = new ChatDisplay("Placeholder Test"); @@ -590,18 +596,18 @@ public void placeholdersTestCommand(CommandSender sender, String translated = Prison.get().getPlatform().getPlaceholders() .placeholderTranslateText( playerUuid, playerName, text ); - builder.add( String.format( "&a Include one or more Prison placeholders with other text...")); - builder.add( String.format( "&a Use { } to escape the placeholders.")); - - // Show player info here like with the search: - if ( player != null ) { - builder.add( String.format( "&a Player: &7%s &aPlayerUuid: &7%s", player.getName(), - (playerUuid == null ? "null" : playerUuid.toString()))); - - } - - - builder.add( String.format( "&7 Original: \\Q%s\\E", text)); + if ( !isShort ) { + builder.add( String.format( "&a Include one or more Prison placeholders with other text...")); + builder.add( String.format( "&a Use { } to escape the placeholders.")); + + // Show player info here like with the search: + if ( player != null ) { + builder.add( String.format( "&a Player: &7%s &aPlayerUuid: &7%s", player.getName(), + (playerUuid == null ? "null" : playerUuid.toString()))); + } + + builder.add( String.format( "&7 Original: \\Q%s\\E", text)); + } builder.add( String.format( "&7 Translated: %s", translated)); From 8d66e4540704b0222175fcb92b7df9a760106f05 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sun, 8 Oct 2023 04:33:52 -0400 Subject: [PATCH 136/151] Placeholders: Added support for a new placeholder attribute to better format time based placeholders. --- docs/changelog_v3.3.x.md | 3 + .../PlaceholderAttributeNumberFormat.java | 6 +- .../PlaceholderAttributeText.java | 6 +- .../PlaceholderAttributeTime.java | 253 ++++++++++++++++++ .../placeholders/PlaceholderIdentifier.java | 13 + .../placeholders/PlaceholderManager.java | 24 +- .../placeholders/PlaceholderManagerUtils.java | 9 +- .../prison/placeholders/PlaceholdersUtil.java | 25 ++ .../java/tech/mcprison/prison/util/Text.java | 82 +++++- .../mcprison/prison/util/TextMessage.java | 10 +- .../prison/mines/managers/MineManager.java | 7 + .../prison/ranks/managers/RankManager.java | 2 + 12 files changed, 431 insertions(+), 9 deletions(-) create mode 100644 prison-core/src/main/java/tech/mcprison/prison/placeholders/PlaceholderAttributeTime.java diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 409e6b065..64bdc2ea8 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -17,6 +17,9 @@ These change logs represent the work that has been going on within prison. # 3.3.0-alpha.15g 2023-10-08 +* **Placeholders: Added support for a new placeholder attribute to better format time based placeholders.** + + * **Placeholders: Added the ability to provide a shorted output of the command `/prison placeholders test` so it only shows the command header and the results.** diff --git a/prison-core/src/main/java/tech/mcprison/prison/placeholders/PlaceholderAttributeNumberFormat.java b/prison-core/src/main/java/tech/mcprison/prison/placeholders/PlaceholderAttributeNumberFormat.java index 2427dca20..023e5e733 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/placeholders/PlaceholderAttributeNumberFormat.java +++ b/prison-core/src/main/java/tech/mcprison/prison/placeholders/PlaceholderAttributeNumberFormat.java @@ -19,7 +19,7 @@ * *

Usage: *

- *
::nFormat:format:spaces:unitType:hex:hex2:debug
+ *
::nFormat:format:spaces:unitType:hex:hex2:debug:player=<playerName>
* *
    *
  • nFormat: the keyword to identify this attribute.
  • @@ -66,6 +66,10 @@ * will log to the console the status of this attribute, along with * any error messages that may occur when applying the attribute. * + *
  • player=<playerName>: Optional. Case insensitive. Non-positional; can be + * placed anywhere. Provides a player for the placeholder when the + * plugin requesting the placeholder cannot request it based upon the player. + *
  • *
* * diff --git a/prison-core/src/main/java/tech/mcprison/prison/placeholders/PlaceholderAttributeText.java b/prison-core/src/main/java/tech/mcprison/prison/placeholders/PlaceholderAttributeText.java index 456b0f81c..06d75ed15 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/placeholders/PlaceholderAttributeText.java +++ b/prison-core/src/main/java/tech/mcprison/prison/placeholders/PlaceholderAttributeText.java @@ -18,7 +18,7 @@ * *

Usage: *

- *
::text:hex:hex1:debug
+ *
::text:hex:hex1:debug:player=<playerName>
* *
    *
  • hex: Optional. Case sensitive. Non-positional; can be placed anywhere. @@ -37,6 +37,10 @@ * will log to the console the status of this attribute, along with * any error messages that may occur when applying the attribute. *
  • + *
  • player=<playerName>: Optional. Case insensitive. Non-positional; can be + * placed anywhere. Provides a player for the placeholder when the + * plugin requesting the placeholder cannot request it based upon the player. + *
  • *
* * diff --git a/prison-core/src/main/java/tech/mcprison/prison/placeholders/PlaceholderAttributeTime.java b/prison-core/src/main/java/tech/mcprison/prison/placeholders/PlaceholderAttributeTime.java new file mode 100644 index 000000000..b96edc9c4 --- /dev/null +++ b/prison-core/src/main/java/tech/mcprison/prison/placeholders/PlaceholderAttributeTime.java @@ -0,0 +1,253 @@ +package tech.mcprison.prison.placeholders; + +import java.text.DecimalFormat; +import java.util.ArrayList; + +import org.apache.commons.lang3.StringUtils; + +import tech.mcprison.prison.Prison; +import tech.mcprison.prison.output.Output; +import tech.mcprison.prison.placeholders.PlaceholderManager.NumberTransformationUnitTypes; +import tech.mcprison.prison.placeholders.PlaceholderManager.TimeTransformationUnitTypes; +import tech.mcprison.prison.util.Text; + +/** + *

This takes the placeholder attribute for time formatting + * and parses the dynamic content to setup this instance. + * Then this class applies the formatting to the generated placeholder + * results to produce the requested output. + *

+ * + *

Usage: + *

+ *
::time:spaces:unitType:hex:hex2:debug:player=
+ * + *

NOTE: 'format' is not used, so just collapse it and provide nothing as shown here. + * If any value is provided, it will be ignored. + *

::nFormat::spaces:unitType:hex:hex2:debug:player=
+ * + *
    + *
  • time: the keyword to identify this attribute.
  • + * + *
  • spaces: number of spaces between format and unit of measure. + * Optional. Defaults to 1.
  • + *
  • unitType: unit type to display or to use to transform the results. + * Optional. Defaults to 'long'. The control of these values + * can be found in the core language files. + * + *
      + *
    • long: Uses the long form of time and date units. Uses both the + * 'core_text__time_units_singular' and + * 'core_text__time_units_plural' language file settings.
    • + *
    • short: Uses the short form of time and date units. These are + * generally a single character each. Uses the + * 'core_text__time_units_short' language file settings.
    • + *
    • colons: Uses colons for the units, except for year, month, + * and week, it uses the same settings as found in the + * 'short' unit
    • + *
    + *
  • + * + *
  • hex: Optional. Case sensitive. Non-positional; can be placed anywhere. + * Only valid value is "hex". When enabled it will translate + * hex color codes, and other color codes before sending the placeholder + * results back to the requestor. This is useful for plugins that + * do not directly support hex color codes. + *
  • hex2: Optional. Case sensitive. Non-positional; can be placed anywhere. + * Only valid value is "hex2". When enabled it will translate + * hex color codes to their intermediate state, which uses '&' color + * codes, sending the placeholder results back to the requestor. + * This is useful for plugins that do not directly support hex + * color codes and may work when 'hex' does not. + *
  • debug: Optional. Case sensitive. Non-positional; can be placed anywhere. + * Only valid value is "debug". When enabled it + * will log to the console the status of this attribute, along with + * any error messages that may occur when applying the attribute. + *
  • + *
  • player=<playerName>: Optional. Case insensitive. Non-positional; can be + * placed anywhere. Provides a player for the placeholder when the + * plugin requesting the placeholder cannot request it based upon the player. + *
  • + *
+ * + * + */ +public class PlaceholderAttributeTime + extends PlaceholderAttributeNumberFormat { + + private TimeTransformationUnitTypes timeUnitType; + +// private ArrayList parts; +// private String raw; +// +// private boolean hex = false; +// private boolean hex2 = false; +// private boolean debug = false; +// +// private String player = null; + + + /** + *

The constructor parameters are exactly the same as the nFormat. + *

+ * + * @param parts + * @param raw + */ + public PlaceholderAttributeTime( ArrayList parts, String raw ) { + super( parts, raw); + + + // Override the unitType: + + // unitType: + String unitTypeStr = parts.size() > 3 ? parts.get( 3 ) : null; + TimeTransformationUnitTypes timeUnitType = + TimeTransformationUnitTypes.fromString( unitTypeStr ); + + setTimeUnitType( timeUnitType ); + + } + + @Override + public String format(Long value) { + String results = null; + + String spaces = StringUtils.repeat( " ", getSpaces() ); + + try { + // & will not work in the DecimalFormat so replace it with ^|^ then replace after formatting: + //String fmt = getFormat();//.replace( "&", "^|^" ); + //DecimalFormat dFmt = Prison.get().getDecimalFormat( fmt ); + + switch ( getTimeUnitType() ) + { + case none: + + results = PlaceholdersUtil.formattedTime( value ); + break; + + case LONG: + results = PlaceholdersUtil.formattedTime( value, spaces ); + break; + + case SHORT: + results = PlaceholdersUtil.formattedShortTime( value, spaces ); + break; + + case colons: + results = PlaceholdersUtil.formattedColonsTime( value, spaces ); + break; + + default: + break; + } + +// if ( results.contains( "^|^" ) ) { +// //results = results.replace( "^|^", "&" ); +// } + + } + catch (Exception e ) { + // Ignore unless in debug mode: + if ( isDebug() ) { + Output.get().logError( + String.format( "Error formatting results. long value= %s " + + "spaces=%d timeUnitType= %s ERRROR: %s", + + Double.toString( value ), getSpaces(), + getTimeUnitType(), e.getMessage() + )); + } + } + + + if ( isHex2() ) { + results = Text.translateAmpColorCodesAltHexCode( results ); + } + else if ( isHex() ) { + results = Text.translateAmpColorCodes( results ); + } + + if ( isDebug() ) { + String rawResults = Text.escapeAmpCodes(results); + String rawAttribute = Text.escapeAmpCodes(getRaw()); + + String message = String.format( "Placeholder Attribute time: double value= %s " + + "spaces=%d timeUnitType=%s Results: [%s] " + + "raw: &3[&7%s&3] &3[&7%s&3]" + + "(remove :debug from placeholder to disable this message)", + + Double.toString( value ), getSpaces(), + getTimeUnitType(), results, rawResults, rawAttribute + ); + Output.get().logInfo( message ); + } + + return results; + + } + + /** + * Not used. + */ + @Override + public String format(String value) { + String results = null; + + try { + long lValue = Long.parseLong( value ); + results = format( lValue ); + } + catch (Exception e ) { + // Ignore unless in debug mode: + if ( isDebug() ) { + Output.get().logError( + String.format( "Error parsing value to a long. String value= [%s] " + + "spaces=%d timeUnitType= %s ERRROR: %s", + + value, getSpaces(), + getTimeUnitType(), e.getMessage() + )); + } + } + + return results; + } + + + + @Override + public String format(Double value) { + String results = null; + + try { + long lValue = value.longValue(); + + results = format( lValue ); + } + catch (Exception e ) { + // Ignore unless in debug mode: + if ( isDebug() ) { + Output.get().logError( + String.format( "Error parsing value to a long. String value= [%s] " + + "spaces=%d timeUnitType= %s ERRROR: %s", + + value, getSpaces(), + getTimeUnitType(), e.getMessage() + )); + } + } + + return results; + } + + public TimeTransformationUnitTypes getTimeUnitType() { + return timeUnitType; + } + public void setTimeUnitType(TimeTransformationUnitTypes timeUnitType) { + this.timeUnitType = timeUnitType; + } + + +} diff --git a/prison-core/src/main/java/tech/mcprison/prison/placeholders/PlaceholderIdentifier.java b/prison-core/src/main/java/tech/mcprison/prison/placeholders/PlaceholderIdentifier.java index 0d611bd37..a9409b9d4 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/placeholders/PlaceholderIdentifier.java +++ b/prison-core/src/main/java/tech/mcprison/prison/placeholders/PlaceholderIdentifier.java @@ -265,6 +265,19 @@ public PlaceholderAttributeText getAttributeText() { return phAttribute; } + public PlaceholderAttributeTime getAttributeTime() { + PlaceholderAttributeTime phAttribute = null; + + for (PlaceholderAttribute placeholderAttribute : getAttributes() ) { + if ( placeholderAttribute instanceof PlaceholderAttributeTime ) { + phAttribute = (PlaceholderAttributeTime) placeholderAttribute; + break; + } + } + + return phAttribute; + } + public String getIdentifierRaw() { return identifierRaw; } diff --git a/prison-core/src/main/java/tech/mcprison/prison/placeholders/PlaceholderManager.java b/prison-core/src/main/java/tech/mcprison/prison/placeholders/PlaceholderManager.java index ed75add67..3a15958e2 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/placeholders/PlaceholderManager.java +++ b/prison-core/src/main/java/tech/mcprison/prison/placeholders/PlaceholderManager.java @@ -95,7 +95,8 @@ public boolean hasSequence() { public enum PlaceholderAttributePrefixes { nFormat, bar, - text; + text, + time; public static PlaceholderAttributePrefixes fromString( String value ) { PlaceholderAttributePrefixes pap = null; @@ -133,6 +134,27 @@ public static NumberTransformationUnitTypes fromString( String value ) { } } + public enum TimeTransformationUnitTypes { + none, + LONG, + SHORT, + colons; + + public static TimeTransformationUnitTypes fromString( String value ) { + TimeTransformationUnitTypes pap = none; + + if ( value != null ) { + for ( TimeTransformationUnitTypes nTrans : values() ) { + if ( nTrans.name().equalsIgnoreCase( value ) ) { + pap = nTrans; + } + } + } + + return pap; + } + } + /** *

The given place holders should have both the prison prefix and without, * with the without having the suppress value set. The suppressable items diff --git a/prison-core/src/main/java/tech/mcprison/prison/placeholders/PlaceholderManagerUtils.java b/prison-core/src/main/java/tech/mcprison/prison/placeholders/PlaceholderManagerUtils.java index f6c3bff67..6b7ff9aec 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/placeholders/PlaceholderManagerUtils.java +++ b/prison-core/src/main/java/tech/mcprison/prison/placeholders/PlaceholderManagerUtils.java @@ -97,7 +97,8 @@ private PlaceholderAttribute attributeFactory( String rawAttribute ) { if ( rawAttribute != null && !rawAttribute.isEmpty() ) { ArrayList parts = new ArrayList<>(); - parts.addAll( Arrays.asList( rawAttribute.split( PlaceholderManager.PRISON_PLACEHOLDER_ATTRIBUTE_FIELD_SEPARATOR )) ); + parts.addAll( Arrays.asList( + rawAttribute.split( PlaceholderManager.PRISON_PLACEHOLDER_ATTRIBUTE_FIELD_SEPARATOR )) ); if ( parts.size() >= 0 ) { PlaceholderAttributePrefixes pap = PlaceholderAttributePrefixes.fromString( parts.get( 0 ) ); @@ -118,6 +119,12 @@ private PlaceholderAttribute attributeFactory( String rawAttribute ) { attribute = new PlaceholderAttributeText( parts, rawAttribute ); break; + case time: + // Insert the dummy value "format" as the second element of 'parts' since Time does not use it: + parts.add(1, ""); + attribute = new PlaceholderAttributeTime( parts, rawAttribute ); + break; + default: break; } diff --git a/prison-core/src/main/java/tech/mcprison/prison/placeholders/PlaceholdersUtil.java b/prison-core/src/main/java/tech/mcprison/prison/placeholders/PlaceholdersUtil.java index a1efb18b4..101ebca6e 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/placeholders/PlaceholdersUtil.java +++ b/prison-core/src/main/java/tech/mcprison/prison/placeholders/PlaceholdersUtil.java @@ -48,6 +48,31 @@ public class PlaceholdersUtil } } + public static String formattedShortTime( double timeSec, String spaces ) { + + long durationMs = (long) (timeSec * 1000d); + String formattedTime = Text.getTimeUntilShortString( durationMs, spaces ); + + return formattedTime; + } + public static String formattedColonsTime( double timeSec, String spaces ) { + + long durationMs = (long) (timeSec * 1000d); + String formattedTime = Text.getTimeUntilColonsString( durationMs, spaces ); + + String textAnd = " " + Text.coreOutputTextAndMsg() + " "; + + formattedTime = formattedTime.replace( textAnd, "" ); + + return formattedTime; + } + public static String formattedTime( double timeSec, String spaces ) { + + long durationMs = (long) (timeSec * 1000d); + String formattedTime = Text.getTimeUntilString( durationMs, spaces ); + + return formattedTime; + } /** *

Formats seconds to 0d 0h 0m 0s. diff --git a/prison-core/src/main/java/tech/mcprison/prison/util/Text.java b/prison-core/src/main/java/tech/mcprison/prison/util/Text.java index 01088b199..c9af8c48f 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/util/Text.java +++ b/prison-core/src/main/java/tech/mcprison/prison/util/Text.java @@ -63,6 +63,26 @@ public class Text "minute:minutes", millisPerMinute, "second:seconds", millisPerSecond); + private static Map unitMillisShort = CollectionUtil + .map( + "y", millisPerYear, + "m", millisPerMonth, + "w", millisPerWeek, + "d", millisPerDay, + "h", millisPerHour, + "m", millisPerMinute, + "s", millisPerSecond); + + private static Map unitMillisColons = CollectionUtil + .map( + "y", millisPerYear, + "m", millisPerMonth, + "w", millisPerWeek, + "day:", millisPerDay, + "hour:", millisPerHour, + "min:", millisPerMinute, + "", millisPerSecond); + private static String unit_time_text_prefix = "&3"; private static String unit_time_text_just_now = "just now"; private static String unit_time_text_ago = "ago"; @@ -115,6 +135,9 @@ public static void initialize() { String timeUnitsSingular = coreOutputTextTimeUnitsSingularMsg(); String timeUnitsPlural = coreOutputTextTimeUnitsPluralMsg(); + + String timeUnitsShort = coreOutputTextTimeUnitsShortMsg(); + String[] tuS = timeUnitsSingular.split( "," ); String[] tuP = timeUnitsPlural.split( "," ); @@ -131,6 +154,40 @@ public static void initialize() { unitMillis.put( tuS[i] + ":" + tuP[i++], millisPerMinute ); unitMillis.put( tuS[i] + ":" + tuP[i++], millisPerSecond ); } + + + String[] tuShort = timeUnitsShort.split( "," ); + + if ( tuShort.length == 7 ) { + unitMillisShort = new LinkedHashMap<>(); + + int i = 0; + unitMillisShort.put( tuShort[i++], millisPerYear ); + unitMillisShort.put( tuShort[i++], millisPerMonth ); + unitMillisShort.put( tuShort[i++], millisPerWeek ); + unitMillisShort.put( tuShort[i++], millisPerDay ); + unitMillisShort.put( tuShort[i++], millisPerHour ); + unitMillisShort.put( tuShort[i++], millisPerMinute ); + unitMillisShort.put( tuShort[i++], millisPerSecond ); + + } + + if ( tuShort.length == 7 ) { + unitMillisColons = new LinkedHashMap<>(); + + int i = 0; + unitMillisColons.put( tuShort[i++], millisPerYear ); + unitMillisColons.put( tuShort[i++], millisPerMonth ); + unitMillisColons.put( tuShort[i++], millisPerWeek ); + unitMillisColons.put( "day:", millisPerDay ); + unitMillisColons.put( "hour:", millisPerHour ); + unitMillisColons.put( "min:", millisPerMinute ); + unitMillisColons.put( "", millisPerSecond ); + + } + + + } /** @@ -572,18 +629,33 @@ public static String tab(String text) { * @return The human-readable string. */ public static String getTimeUntilString(long millis) { + return getTimeUntilString( millis, unitMillis, unitPrefixSpacer, null ); + } + public static String getTimeUntilString(long millis, String spaces ) { + return getTimeUntilString( millis, unitMillis, spaces, null ); + } + public static String getTimeUntilShortString(long millis, String spaces ) { + return getTimeUntilString( millis, unitMillisShort, spaces, null ); + } + public static String getTimeUntilColonsString(long millis, String spaces ) { + DecimalFormat dFmt = new DecimalFormat( "00" ); + return getTimeUntilString( millis, unitMillisColons, spaces, dFmt ); + } + private static String getTimeUntilString(long millis, Map units, + String unitSpacer, DecimalFormat dFmt ) { String ret = unit_time_text_prefix; double millisLeft = (double) Math.abs(millis); List unitCountParts = new ArrayList<>(); - for (Map.Entry entry : unitMillis.entrySet()) { + for (Map.Entry entry : units.entrySet()) { if (unitCountParts.size() == 3) { break; } + boolean isColons = ( entry.getKey().endsWith( ":" ) ); String[] unitNames = entry.getKey().split( ":" ); - String unitNameSingular = unitNames[0]; - String unitNamePlural = unitNames.length > 1 ? unitNames[1] : unitNames[0]; + String unitNameSingular = isColons ? ":" : unitNames[0]; + String unitNamePlural = isColons ? ":" : unitNames.length > 1 ? unitNames[1] : unitNames[0]; long unitSize = entry.getValue(); long unitCount = (long) Math.floor(millisLeft / unitSize); @@ -592,7 +664,9 @@ public static String getTimeUntilString(long millis) { } millisLeft -= unitSize * unitCount; - unitCountParts.add(unitCount + unitPrefixSpacer + + String unitCountStr = dFmt == null ? Long.toString( unitCount ) : dFmt.format( unitCount ); + + unitCountParts.add( unitCountStr + unitSpacer + ( unitCount == 1 ? unitNameSingular : unitNamePlural) ); } diff --git a/prison-core/src/main/java/tech/mcprison/prison/util/TextMessage.java b/prison-core/src/main/java/tech/mcprison/prison/util/TextMessage.java index 7d3ebf2ce..7d5c3b9c8 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/util/TextMessage.java +++ b/prison-core/src/main/java/tech/mcprison/prison/util/TextMessage.java @@ -46,7 +46,7 @@ protected static String coreOutputTextFromNowMsg() { .localize(); } - protected static String coreOutputTextAndMsg() { + public static String coreOutputTextAndMsg() { return Prison.get().getLocaleManager() .getLocalizable( "core_text__and" ) .withReplacements( "%s" ) @@ -77,5 +77,13 @@ protected static String coreOutputTextTimeUnitsPluralMsg() { .setFailSilently() .localize(); } + + protected static String coreOutputTextTimeUnitsShortMsg() { + return Prison.get().getLocaleManager() + .getLocalizable( "core_text__time_units_short" ) + .withReplacements( "%s" ) + .setFailSilently() + .localize(); + } } diff --git a/prison-mines/src/main/java/tech/mcprison/prison/mines/managers/MineManager.java b/prison-mines/src/main/java/tech/mcprison/prison/mines/managers/MineManager.java index 91e6ea570..680fc725b 100644 --- a/prison-mines/src/main/java/tech/mcprison/prison/mines/managers/MineManager.java +++ b/prison-mines/src/main/java/tech/mcprison/prison/mines/managers/MineManager.java @@ -45,6 +45,7 @@ import tech.mcprison.prison.placeholders.PlaceholderAttributeBar; import tech.mcprison.prison.placeholders.PlaceholderAttributeNumberFormat; import tech.mcprison.prison.placeholders.PlaceholderAttributeText; +import tech.mcprison.prison.placeholders.PlaceholderAttributeTime; import tech.mcprison.prison.placeholders.PlaceholderIdentifier; import tech.mcprison.prison.placeholders.PlaceholderManager; import tech.mcprison.prison.placeholders.PlaceholderManager.PlaceholderFlags; @@ -775,6 +776,8 @@ public String getTranslateMinesPlaceholder( PlaceholderIdentifier identifier ) { PlaceholderAttributeBar attributeBar = identifier.getAttributeBar(); PlaceholderAttributeNumberFormat attributeNFormat = identifier.getAttributeNFormat(); PlaceholderAttributeText attributeText = identifier.getAttributeText(); + PlaceholderAttributeTime attributeTime = identifier.getAttributeTime(); + int sequence = identifier.getSequence(); @@ -828,6 +831,10 @@ public String getTranslateMinesPlaceholder( PlaceholderIdentifier identifier ) { results = attributeNFormat.format( (long) mine.getResetTime() ); } + else if ( attributeTime != null ) { + + results = attributeTime.format( (long) mine.getResetTime() ); + } else { results = iFmt.format( mine.getResetTime() ); diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/managers/RankManager.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/managers/RankManager.java index 38766cc23..c4d6d20d8 100644 --- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/managers/RankManager.java +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/managers/RankManager.java @@ -37,6 +37,7 @@ import tech.mcprison.prison.placeholders.PlaceholderAttributeBar; import tech.mcprison.prison.placeholders.PlaceholderAttributeNumberFormat; import tech.mcprison.prison.placeholders.PlaceholderAttributeText; +import tech.mcprison.prison.placeholders.PlaceholderAttributeTime; import tech.mcprison.prison.placeholders.PlaceholderIdentifier; import tech.mcprison.prison.placeholders.PlaceholderManager; import tech.mcprison.prison.placeholders.PlaceholderManager.PlaceholderFlags; @@ -718,6 +719,7 @@ public String getTranslateRanksPlaceHolder( PlaceholderIdentifier identifier ) { PlaceholderAttributeBar attributeBar = identifier.getAttributeBar(); PlaceholderAttributeNumberFormat attributeNFormat = identifier.getAttributeNFormat(); PlaceholderAttributeText attributeText = identifier.getAttributeText(); + PlaceholderAttributeTime attributeTime = identifier.getAttributeTime(); int sequence = identifier.getSequence(); From eb7cce2459495c698c5f16385b8c6d558f6ab0a7 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sun, 8 Oct 2023 23:43:00 -0400 Subject: [PATCH 137/151] Prison Debug: Added support to target some debug logging to a specific player. When enabled, it will ignore all other players. Not all debug messages have been hooked up. More can be added upon request. When debug mode is disabled, it will remove the debug player name. --- docs/changelog_v3.3.x.md | 5 ++ .../tech/mcprison/prison/PrisonCommand.java | 51 +++++++++++++++- .../tech/mcprison/prison/output/Output.java | 60 ++++++++++++++++--- .../prison/tasks/PrisonCommandTasks.java | 6 +- .../autofeatures/AutoManagerFeatures.java | 5 +- .../prison/spigot/sellall/SellAllData.java | 2 +- 6 files changed, 112 insertions(+), 17 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 64bdc2ea8..1e6818a00 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -17,6 +17,11 @@ These change logs represent the work that has been going on within prison. # 3.3.0-alpha.15g 2023-10-08 +* **Prison Debug: Added support to target some debug logging to a specific player.** +When enabled, it will ignore all other players. Not all debug messages have been hooked up. More can be added upon request. +When debug mode is disabled, it will remove the debug player name. + + * **Placeholders: Added support for a new placeholder attribute to better format time based placeholders.** diff --git a/prison-core/src/main/java/tech/mcprison/prison/PrisonCommand.java b/prison-core/src/main/java/tech/mcprison/prison/PrisonCommand.java index ada535123..fe810f237 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/PrisonCommand.java +++ b/prison-core/src/main/java/tech/mcprison/prison/PrisonCommand.java @@ -1117,7 +1117,8 @@ public void autoFeaturesInformation(CommandSender sender) { @Command(identifier = "prison debug", description = "Enables debugging and trouble shooting information. " + - "For internal use only. Do not use unless instructed.", + "For internal use only. Do not use unless instructed. This will add a lot of " + + "data to the console.", onlyPlayers = false, permissions = "prison.debug", aliases = {"prison support debug"} ) public void toggleDebug(CommandSender sender, @@ -1125,16 +1126,39 @@ public void toggleDebug(CommandSender sender, @Arg(name = "targets", def = " ", description = "Optional. Enable or disable a debugging target, or set a count down timer. " + "[on, off, targets, (count-down-timer), selective, jarScan, " + - "testPlayerUtil, testLocale, rankup ] " + + "testPlayerUtil, testLocale, rankup, player= ] " + "Use 'targets' to list all available targets. Use 'on' or 'off' to toggle " + "on and off individual targets, or 'all' targets if no target is specified. " + "If any targets are enabled, then debug in general will be enabled. Selective will only " + "activate debug with the specified targets. " + "A positive integer value will enable the count down timer mode to enable " + "debug mode for a number of loggings, then debug mode will be turned off. " + - "jarScan will identify what Java version compiled the class files within the listed jars." + "jarScan will identify what Java version compiled the class files within the listed jars. " + + "If a player name is given, all debug messages that are tracked by player name will only be " + + "logged for that player. Example: `/debug playerName=RoyalBlueRanger 5` will log only " + + "5 debug messages for that player, then debug mode will be disabled. " ) String targets ) { + String playerName = null; + + String playerStr = extractParameter("player=", targets); + if ( playerStr != null ) { + targets = targets.replace( playerStr, "" ); + playerName = playerStr.replace( "player=", "" ).trim(); + + if ( playerName != null ) { + + Output.get().setDebugPlayerName( playerName ); + + sender.sendMessage( "Prison Debug Mode enabled only for player: " + playerName ); + } + else { + Output.get().setDebugPlayerName( null ); + + sender.sendMessage( "Prison Debug Only-for-player Mode has been disabled. Debug mode will be logged for all players." ); + } + } + if ( targets != null && "jarScan".equalsIgnoreCase( targets ) ) { PrisonJarReporter pjr = new PrisonJarReporter(); @@ -1199,6 +1223,27 @@ public void toggleDebug(CommandSender sender, } + + private String extractParameter( String key, String options ) { + return extractParameter( key, options, true ); + } + private String extractParameter( String key, String options, boolean tryLowerCase ) { + String results = null; + int idx = options.indexOf( key ); + if ( idx != -1 ) { + int idxEnd = options.indexOf( " ", idx ); + if ( idxEnd == -1 ) { + idxEnd = options.length(); + } + results = options.substring( idx, idxEnd ); + } + else if ( tryLowerCase ) { + // try again, but lowercase the key + results = extractParameter( key.toLowerCase(), options, false ); + } + return results; + } + @Command(identifier = "prison findCmd", description = "For internal use only. Do not use. This command is used by internal code to look up " + diff --git a/prison-core/src/main/java/tech/mcprison/prison/output/Output.java b/prison-core/src/main/java/tech/mcprison/prison/output/Output.java index 658e7ab54..85b5ef47d 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/output/Output.java +++ b/prison-core/src/main/java/tech/mcprison/prison/output/Output.java @@ -28,6 +28,7 @@ import tech.mcprison.prison.Prison; import tech.mcprison.prison.internal.CommandSender; +import tech.mcprison.prison.internal.Player; /** * Standardized output to the console and to players. @@ -65,6 +66,8 @@ public class Output private Set selectiveDebugTargets; private int debugCountDown = -1; + + private String debugPlayerName = null; public enum DebugTarget { all, @@ -374,24 +377,45 @@ public void logError(String message, Throwable... throwable) { } public void logDebug(String message, Object... args) { + logDebug( message, null, args ); + } + public void logDebug(String message, Player player, Object... args) { if ( isDebug() ) { - if ( debugCountDown != -1 && debugCountDown-- == 1 ) { - setDebugCountDown( -1 ); - setDebug( false ); + + if ( getDebugPlayerName() == null || + getDebugPlayerName() != null && player != null && + getDebugPlayerName().equalsIgnoreCase( player.getName() ) ) { + + if ( debugCountDown != -1 && debugCountDown-- == 1 ) { + setDebugCountDown( -1 ); + setDebug( false ); + setDebugPlayerName( null ); + } + log(message, LogLevel.DEBUG, args); } - log(message, LogLevel.DEBUG, args); } } public void logDebug( DebugTarget debugTarget, String message, Object... args) { + logDebug( debugTarget, message, null, args ); + } + + public void logDebug( DebugTarget debugTarget, String message, Player player, Object... args) { if ( isDebug( debugTarget ) ) { - if ( debugCountDown != -1 && debugCountDown-- == 1 ) { - setDebugCountDown( -1 ); - setDebug( false ); - } - log(message, LogLevel.DEBUG, args); + + if ( getDebugPlayerName() == null || + getDebugPlayerName() != null && player != null && + getDebugPlayerName().equalsIgnoreCase( player.getName() ) ) { + + if ( debugCountDown != -1 && debugCountDown-- == 1 ) { + setDebugCountDown( -1 ); + setDebug( false ); + setDebugPlayerName( null ); + } + log(message, LogLevel.DEBUG, args); // logDebug(message, args ); + } } // // The following is not yet enabled since the user interfaces are not in place to manage the set: @@ -439,6 +463,9 @@ public void applyDebugTargets( String targets ) { setDebugCountDown( -1 ); setDebug( false ); + // If turning off debug mode, then reset only-for-player name to null: + setDebugPlayerName( null ); + log( "Prison Debugger Disabled: Count down timer is disabled: %d", LogLevel.DEBUG, countDownNumber ); return; } @@ -469,9 +496,17 @@ public void applyDebugTargets( String targets ) { // No targets were set, so just toggle the debugger: Output.get().setDebug( !Output.get().isDebug() ); + // Clear all existing targets: getActiveDebugTargets().clear(); + + + // If turning off debug mode, then reset only-for-player name to null: + if ( !isDebug() ) { + setDebugPlayerName( null ); + } + // Turn off the countdown timer if it was set (not -1): if ( !isDebug() && getDebugCountDown() != -1 ) { setDebugCountDown( -1 ); @@ -652,5 +687,12 @@ public String getColorCodeDebug() { return colorCodeDebug; } + + public String getDebugPlayerName() { + return debugPlayerName; + } + public void setDebugPlayerName(String debugPlayerName) { + this.debugPlayerName = debugPlayerName; + } } diff --git a/prison-core/src/main/java/tech/mcprison/prison/tasks/PrisonCommandTasks.java b/prison-core/src/main/java/tech/mcprison/prison/tasks/PrisonCommandTasks.java index 8706a810d..4a39bdb0f 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/tasks/PrisonCommandTasks.java +++ b/prison-core/src/main/java/tech/mcprison/prison/tasks/PrisonCommandTasks.java @@ -69,12 +69,14 @@ public void run() { else if ( Output.get().isDebug() && cmTasksPosition > 0 ) { // Done running all tasks. If debug is enabled, print: + String playerName = getPlayer() != null ? getPlayer().getName() : null; + String message = String.format( "Prison Command Debug Details: %d", cmTasksPosition ); - Output.get().logDebug( message ); + Output.get().logDebug( message, playerName ); for ( PrisonCommandTaskData cmdTask : cmdTasks ) { - Output.get().logInfo( cmdTask.getDebugDetails() ); + Output.get().logDebug( cmdTask.getDebugDetails(), playerName ); } } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerFeatures.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerFeatures.java index a8b96a1ee..5e7e20827 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerFeatures.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerFeatures.java @@ -167,11 +167,12 @@ protected void printDebugInfo( PrisonMinesBlockBreakEvent pmEvent, double start if ( !Output.get().isDebug() && pmEvent.isForceDebugLogging() ) { pmEvent.getDebugInfo().insert(0, Output.get().getColorCodeDebug() ); - Output.get().logInfo( pmEvent.getDebugInfo().toString() ); + + Output.get().logInfo( pmEvent.getDebugInfo().toString(), pmEvent.getSpigotPlayer() ); } else { - Output.get().logDebug( DebugTarget.blockBreak, pmEvent.getDebugInfo().toString() ); + Output.get().logDebug( DebugTarget.blockBreak, pmEvent.getDebugInfo().toString(), pmEvent.getSpigotPlayer() ); } } } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/sellall/SellAllData.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/sellall/SellAllData.java index 85fe93f33..9d7555fba 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/sellall/SellAllData.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/sellall/SellAllData.java @@ -54,7 +54,7 @@ public String toString() { public static void debugItemsSold( List soldItems, SpigotPlayer sPlayer, double multiplier ) { if ( Output.get().isDebug() ) { String report = SellAllData.itemsSoldReport( soldItems, sPlayer, multiplier ); - Output.get().logInfo( report ); + Output.get().logDebug( report, (sPlayer != null ? sPlayer.getName() : null) ); } } From 5c6dbaecf47e4b513d447a7163856d20ac2ece80 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sun, 8 Oct 2023 23:44:43 -0400 Subject: [PATCH 138/151] Auto Sell: Bug fix for full inventory when auto sell is toggled off, which was incorrectly selling the player's inventory. --- docs/changelog_v3.3.x.md | 3 ++ .../autofeatures/AutoManagerFeatures.java | 44 +++++++++++-------- 2 files changed, 29 insertions(+), 18 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 1e6818a00..9add06216 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -17,6 +17,9 @@ These change logs represent the work that has been going on within prison. # 3.3.0-alpha.15g 2023-10-08 +* **Auto Sell: Bug fix for full inventory when auto sell is toggled off, which was incorrectly selling the player's inventory.** + + * **Prison Debug: Added support to target some debug logging to a specific player.** When enabled, it will ignore all other players. Not all debug messages have been hooked up. More can be added upon request. When debug mode is disabled, it will remove the debug player name. diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerFeatures.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerFeatures.java index 5e7e20827..ca7d99f08 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerFeatures.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerFeatures.java @@ -1457,31 +1457,39 @@ protected void dropExtra( HashMap extra, // if ( SpigotPrison.getInstance().isSellAllEnabled() ) { + SpigotPlayer sPlayer = new SpigotPlayer( player ); - SellAllUtil sellAllUtil = SellAllUtil.get(); + boolean isPlayerAutosellEnabled = sPlayer.isAutoSellEnabled( debugInfo ); - boolean isSellallEnabled = sellAllUtil != null && - SpigotPrison.getInstance().isSellAllEnabled(); + boolean isPlayerAutoSellByPerm = sPlayer.isAutoSellByPermEnabled( isPlayerAutosellEnabled ); + + if ( isPlayerAutosellEnabled || isPlayerAutoSellByPerm ) { + + SellAllUtil sellAllUtil = SellAllUtil.get(); - // This will return true (allow autosell) unless players can toggle autosell and they turned it off: - // This is to be used with other auto sell setting, but never on it's own: - boolean isPlayerAutosellEnabled = - isSellallEnabled && - (!sellAllUtil.isAutoSellPerUserToggleable || - sellAllUtil.isSellallPlayerUserToggleEnabled( - player )); +// boolean isSellallEnabled = sellAllUtil != null && +// SpigotPrison.getInstance().isSellAllEnabled(); +// +// // This will return true (allow autosell) unless players can toggle autosell and they turned it off: +// // This is to be used with other auto sell setting, but never on it's own: +// boolean isPlayerAutosellEnabled = +// isSellallEnabled && +// (!sellAllUtil.isAutoSellPerUserToggleable || +// sellAllUtil.isSellallPlayerUserToggleEnabled( +// player )); - // On inventory is full, will auto sell if auto sell is enabled in either - // the sellall configs, or the auto feature configs. - if (sellAllUtil != null && ( - sellAllUtil.isAutoSellEnabled || - autoSell )) { -// isBoolean(AutoFeatures.isAutoSellIfInventoryIsFull) )) { +// // On inventory is full, will auto sell if auto sell is enabled in either +// // the sellall configs, or the auto feature configs. +// if (sellAllUtil != null && ( +// sellAllUtil.isAutoSellEnabled || +// autoSell )) { +//// isBoolean(AutoFeatures.isAutoSellIfInventoryIsFull) )) { - if ( isPlayerAutosellEnabled ) { + // if ( isPlayerAutosellEnabled ) + { boolean saNote = sellAllUtil.isAutoSellNotificationEnabled; @@ -1532,7 +1540,7 @@ protected void dropExtra( HashMap extra, debugInfo.append( " ] " ); - SpigotPlayer sPlayer = new SpigotPlayer( player ); + //SpigotPlayer sPlayer = new SpigotPlayer( player ); PlayerAutoRankupTask.autoSubmitPlayerRankupTask( sPlayer, debugInfo ); } From 0b3153912a9d7f9289f3ee4d863602f8eedba5bf Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Mon, 9 Oct 2023 00:16:25 -0400 Subject: [PATCH 139/151] Placeholder attribute time: add the time attribute to 4 more placeholders. --- docs/changelog_v3.3.x.md | 5 ++++- .../tech/mcprison/prison/mines/managers/MineManager.java | 9 +++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 9add06216..fc6765135 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -17,6 +17,9 @@ These change logs represent the work that has been going on within prison. # 3.3.0-alpha.15g 2023-10-08 +* **Placeholder attribute time: add the time attribute to 4 more placeholders.** + + * **Auto Sell: Bug fix for full inventory when auto sell is toggled off, which was incorrectly selling the player's inventory.** @@ -29,7 +32,7 @@ When debug mode is disabled, it will remove the debug player name. * **Placeholders: Added the ability to provide a shorted output of the command `/prison placeholders test` so it only shows the command header and the results.** - +Use the '-s' flag as in: '/prison placeholders test -s' * **Placeholders: bug fix: If using the placeholder attribute for an off line player, it would cause an error when checking if the player was in a disabled world.** diff --git a/prison-mines/src/main/java/tech/mcprison/prison/mines/managers/MineManager.java b/prison-mines/src/main/java/tech/mcprison/prison/mines/managers/MineManager.java index 680fc725b..f53f77ae6 100644 --- a/prison-mines/src/main/java/tech/mcprison/prison/mines/managers/MineManager.java +++ b/prison-mines/src/main/java/tech/mcprison/prison/mines/managers/MineManager.java @@ -794,6 +794,7 @@ public String getTranslateMinesPlaceholder( PlaceholderIdentifier identifier ) { if ( mine != null || placeHolderKey.getPlaceholder().hasFlag( PlaceholderFlags.PLAYERBLOCKS ) || placeHolderKey.getPlaceholder().hasFlag( PlaceholderFlags.MINEPLAYERS )) { + DecimalFormat dFmt = Prison.get().getDecimalFormat("#,##0.00"); DecimalFormat iFmt = Prison.get().getDecimalFormatInt(); // DecimalFormat fFmt = Prison.get().getDecimalForma("#,##0.00"); @@ -853,6 +854,10 @@ else if ( attributeTime != null ) { results = attributeNFormat.format( (long) mine.getResetTime() ); } + else if ( attributeTime != null ) { + + results = attributeTime.format( (long) mine.getResetTime() ); + } else { double timeMif = mine.getResetTime(); @@ -873,6 +878,10 @@ else if ( attributeTime != null ) { results = attributeNFormat.format( (long) mine.getRemainingTimeSec() ); } + else if ( attributeTime != null ) { + + results = attributeTime.format( (long) mine.getResetTime() ); + } else { results = dFmt.format( mine.getRemainingTimeSec() ); } From 5b1d72917ea634a2760cb08726858ecae6187f16 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Thu, 26 Oct 2023 03:02:28 -0400 Subject: [PATCH 140/151] Updated nbt-api and fixed a new issue that was introduced with mc 1.20.2. --- docs/changelog_v3.3.x.md | 5 ++++- prison-spigot/build.gradle | 2 +- .../mcprison/prison/spigot/nbt/PrisonNBTUtil.java | 13 +++++++++++-- 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index fc6765135..7815b3571 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -14,7 +14,10 @@ These change logs represent the work that has been going on within prison. -# 3.3.0-alpha.15g 2023-10-08 +# 3.3.0-alpha.15g 2023-10-26 + + +* **Updated nbt-api and fixed a new issue that was introduced with mc 1.20.2.** * **Placeholder attribute time: add the time attribute to 4 more placeholders.** diff --git a/prison-spigot/build.gradle b/prison-spigot/build.gradle index 2043b884a..1e33b8b42 100644 --- a/prison-spigot/build.gradle +++ b/prison-spigot/build.gradle @@ -192,7 +192,7 @@ dependencies { // https://github.com/tr7zw/Item-NBT-API/wiki/Using-Gradle // https://www.spigotmc.org/resources/nbt-api.7939/ // https://mvnrepository.com/artifact/de.tr7zw/item-nbt-api-plugin - implementation 'de.tr7zw:item-nbt-api:2.11.3' + implementation 'de.tr7zw:item-nbt-api:2.12.0' // implementation 'de.tr7zw:item-nbt-api-plugin:2.11.2' // implementation 'de.tr7zw:item-nbt-api-plugin:2.10.0' // implementation 'de.tr7zw:item-nbt-api-plugin:2.9.2' diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/nbt/PrisonNBTUtil.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/nbt/PrisonNBTUtil.java index c35f26d5d..415409308 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/nbt/PrisonNBTUtil.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/nbt/PrisonNBTUtil.java @@ -1,9 +1,12 @@ package tech.mcprison.prison.spigot.nbt; +import java.util.function.Function; + import org.bukkit.inventory.ItemStack; import de.tr7zw.changeme.nbtapi.NBT; import de.tr7zw.changeme.nbtapi.iface.ReadWriteNBT; +import de.tr7zw.changeme.nbtapi.iface.ReadableItemNBT; import tech.mcprison.prison.output.Output; /** @@ -40,7 +43,10 @@ public static boolean hasNBTString( ItemStack bukkitStack, String key ) { public static String getNBTString( ItemStack bukkitStack, String key ) { String results = null; - results = NBT.get(bukkitStack, nbt -> nbt.getString(key)); + Function gsFnc = nbt -> nbt.getString(key); + + results = NBT.get(bukkitStack, gsFnc ); +// results = NBT.get(bukkitStack, nbt -> nbt.getString(key)); return results; } @@ -59,7 +65,10 @@ public static void setNBTString( ItemStack bukkitStack, String key, String value public static boolean getNBTBoolean( ItemStack bukkitStack, String key ) { boolean results = false; - results = NBT.get(bukkitStack, nbt -> nbt.getBoolean(key)); + Function gbFnc = nbt -> nbt.getBoolean(key); + + results = NBT.get(bukkitStack, gbFnc ); +// results = NBT.get(bukkitStack, nbt -> nbt.getBoolean(key)); return results; } From 1077d73067a416833e5d537024a00c8e63798a5f Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 4 Nov 2023 03:33:06 -0400 Subject: [PATCH 141/151] GUI: Add support for changing the gui item names for Ranks and Mines. Ranks can now set their material type too. --- docs/changelog_v3.3.x.md | 5 +- .../prison/spigot/configs/GuiConfig.java | 91 +++++++++++++++++++ .../spigot/gui/mine/SpigotPlayerMinesGUI.java | 20 +++- .../spigot/gui/rank/SpigotPlayerRanksGUI.java | 43 +++++++-- 4 files changed, 148 insertions(+), 11 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 7815b3571..60447fc15 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -14,7 +14,10 @@ These change logs represent the work that has been going on within prison. -# 3.3.0-alpha.15g 2023-10-26 +# 3.3.0-alpha.15g 2023-11-04 + + +* **GUI: Add support for changing the gui item names for Ranks and Mines. Ranks can now set their material type too.** * **Updated nbt-api and fixed a new issue that was introduced with mc 1.20.2.** diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/configs/GuiConfig.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/configs/GuiConfig.java index 1335180ba..bdf924b1b 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/configs/GuiConfig.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/configs/GuiConfig.java @@ -14,6 +14,8 @@ import tech.mcprison.prison.mines.PrisonMines; import tech.mcprison.prison.mines.data.Mine; import tech.mcprison.prison.output.Output; +import tech.mcprison.prison.ranks.PrisonRanks; +import tech.mcprison.prison.ranks.data.Rank; import tech.mcprison.prison.spigot.SpigotPrison; /** @@ -220,6 +222,95 @@ else if ( conf.get( "Options.Mines.MaterialType.NoMineAccess" ) == null ) { changeCount++; } + + + if ( conf.get( "Options.Ranks.MaterialType" ) == null ) { + + if ( PrisonRanks.getInstance() != null ) { + + LinkedHashMap map = new LinkedHashMap<>(); + + map.put("NoRankAccess", XMaterial.REDSTONE_BLOCK.name() ); + + // Example to preset all ranks: Only do the first 10: + int count = 0; + for ( Rank rank : PrisonRanks.getInstance().getRankManager().getRanks() ) { + map.put( rank.getName(), XMaterial.TRIPWIRE_HOOK.name() ); + if ( ++count >= 10 ) { + break; + } + } + + conf.set("Options.Ranks.MaterialType", map); + changeCount++; + } + } + else if ( conf.get( "Options.Ranks.MaterialType.NoMineAccess" ) == null ) { + + String noMineAccess = XMaterial.REDSTONE_BLOCK.name(); + + conf.set("Options.Ranks.MaterialType.NoMineAccess", noMineAccess ); + changeCount++; + } + + + + if ( conf.get( "Options.Mines.GuiItemNameDefault" ) == null ) { + + String defaultName = "{mineTag}"; + + conf.set("Options.Mines.GuiItemNameDefault", defaultName ); + changeCount++; + } + + if ( conf.get( "Options.Mines.GuiItemNames" ) == null ) { + + if ( PrisonMines.getInstance() != null ) { + + LinkedHashMap map = new LinkedHashMap<>(); + + // Example to preset all mines: Only do the first 10: + int count = 0; + for ( Mine mine : PrisonMines.getInstance().getMineManager().getMines() ) { + map.put( mine.getName(), mine.getTag() ); + if ( ++count >= 10 ) { + break; + } + } + + conf.set("Options.Mines.GuiItemNames", map); + changeCount++; + } + } + + + if ( conf.get( "Options.Ranks.GuiItemNameDefault" ) == null ) { + + String defaultName = "{rankTag}"; + + conf.set("Options.Ranks.GuiItemNameDefault", defaultName ); + changeCount++; + } + if ( conf.get( "Options.Ranks.GuiItemNames" ) == null ) { + + if ( PrisonRanks.getInstance() != null ) { + + LinkedHashMap map = new LinkedHashMap<>(); + + // Example to preset all ranks: Only do the first 10: + int count = 0; + for ( Rank rank : PrisonRanks.getInstance().getRankManager().getRanks() ) { + map.put( rank.getName(), rank.getTag() ); + if ( ++count >= 10 ) { + break; + } + } + + conf.set("Options.Ranks.GuiItemNames", map); + changeCount++; + } + } + // Count and save if (changeCount > 0) { try { diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/mine/SpigotPlayerMinesGUI.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/mine/SpigotPlayerMinesGUI.java index 33437fced..951149bb1 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/mine/SpigotPlayerMinesGUI.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/mine/SpigotPlayerMinesGUI.java @@ -100,7 +100,10 @@ public void open() { // Create GUI but use the gui title as defined within the ConfigGui.yml file: PrisonGUI gui = new PrisonGUI(p, guiPageData.getDimension(), guiConfig.getString("Options.Titles.PlayerMinesGUI")); + + String guiItemNameDefault = guiConfig.getString( "Options.Mines.GuiItemNameDefault" ); + // Load the generic mine LORE that would be displayed first: List configCustomLore = guiConfig.getStringList("EditableLore.Mines"); @@ -122,6 +125,9 @@ public void open() { for (Mine m : minesDisplay) { // for (Mine m : mines.getSortedList()) { + String guiItemName = guiConfig.getString( "Options.Mines.GuiItemNames." + m.getName() ); + + // Init the lore array with default values for ladders ButtonLore minesLore = new ButtonLore(); @@ -140,8 +146,13 @@ public void open() { // Material material; - // Get Mine Name. - String mineName = m.getName(); + // Get Mine Name. First use 'guiItemName' if not null, then try to use 'guiItemNameDefault' + // if not null, and then use the mine's tag, or if that's null, then use the name: + String mineName = + guiItemName != null ? guiItemName : + guiItemNameDefault != null ? guiItemNameDefault : + m.getTag() != null ? m.getTag() : + m.getName(); // // Add mineName lore for TP. // minesLore.addLineLoreAction( "&3" + mineName ); @@ -261,7 +272,8 @@ public void open() { } - Button itemMine = new Button(null, xMat, minesLore, "&3" + mineTag); + Button itemMine = new Button(null, xMat, minesLore, mineName ); +// Button itemMine = new Button(null, xMat, minesLore, "&3" + mineTag); String mineTeleportCommand = Output.stringFormat( @@ -269,7 +281,7 @@ public void open() { m.getName(), p.getName() ); - // Before adding the button, add an NBT tag for the command and rank name: + // Before adding the button, add an NBT tag for the command and mine name: // PrisonNBTUtil nbtUtil = new PrisonNBTUtil(); // NBTItem nbtItem = nbtUtil == null ? null : nbtUtil.getNBT( itemMine.getButtonItem()); PrisonNBTUtil.setNBTBoolean( itemMine.getButtonItem(), SpigotGUIMenuTools.GUI_MENU_TOOLS_NBT_ENABLED, true); diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/rank/SpigotPlayerRanksGUI.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/rank/SpigotPlayerRanksGUI.java index 4b1cccdb2..7e489f599 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/rank/SpigotPlayerRanksGUI.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/rank/SpigotPlayerRanksGUI.java @@ -157,6 +157,11 @@ public void open() { PrisonGUI gui = new PrisonGUI(getPlayer(), guiPageData.getDimension(), guiConfig.getString("Options.Titles.PlayerRanksGUI")); + + + String guiItemNameDefault = guiConfig.getString( "Options.Ranks.GuiItemNameDefault" ); + + // Not sure how you want to represent this: XMaterial materialHas = XMaterial.valueOf(guiConfig.getString("Options.Ranks.Item_gotten_rank")); XMaterial materialHasNot = XMaterial.valueOf(guiConfig.getString("Options.Ranks.Item_not_gotten_rank")); @@ -184,9 +189,34 @@ public void open() { for ( Rank rank : ranksDisplay ) { - // hasAccess uses access by rank, and access by perm: - boolean playerHasThisRank = getRankPlayer() != null && getRankPlayer().hasAccessToRank( rank ); - + + String guiItemName = guiConfig.getString( "Options.Ranks.GuiItemNames." + rank.getName() ); + + // Get Rank Name. First use 'guiItemName' if not null, then try to use 'guiItemNameDefault' + // if not null, and then use the rank's tag, or if that's null, then use the name: + String rankName = + guiItemName != null ? guiItemName : + guiItemNameDefault != null ? guiItemNameDefault : + rank.getTag() != null ? rank.getTag() : + rank.getName(); + + + // hasAccess uses access by rank, and access by perm: + boolean playerHasThisRank = getRankPlayer() != null && getRankPlayer().hasAccessToRank( rank ); + + + // The valid names to use for Options.Ranks.MaterialType. must be + // based upon the XMaterial enumeration name, or supported past names. + String materialTypeStr = guiConfig.getString("Options.Ranks.MaterialType." + rank.getName()); + XMaterial materialType = + materialTypeStr == null ? null : + XMaterial.valueOf( materialTypeStr.toUpperCase() ); + + materialType = + !playerHasThisRank ? materialHasNot : + materialType != null ? materialType : + materialHas; + String rankLoreKey = "EditableLore.Rank." + ladderName + "." + rank.getName(); List rankLore = new ArrayList<>( configCustomLore ); List rankLore2 = guiConfig.getStringList( rankLoreKey ); @@ -215,7 +245,7 @@ public void open() { } for ( String stringValue : rankLore ) { - + String currency = (rank.getCurrency() == null || "default".equalsIgnoreCase( rank.getCurrency()) || rank.getCurrency().trim().length() == 0 ? @@ -246,9 +276,10 @@ public void open() { } Button itemRank = new Button(null, - playerHasThisRank ? materialHas : materialHasNot, + materialType, +// playerHasThisRank ? materialHas : materialHasNot, showNumber ? amount : 1, ranksLore, - rank.getTag() ); + rankName ); amount++; From 9e75e613e35668b850dd678b2af57aa8fcea1e63 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sun, 5 Nov 2023 01:54:29 -0500 Subject: [PATCH 142/151] Player Cache: Put some of the player cache numbers in to the config.yml file so they can be fine tuned if desired. See the changes to config.yml for information to what the new setting controls. --- docs/changelog_v3.3.x.md | 6 +- .../mcprison/prison/cache/PlayerCache.java | 24 +++++-- .../cache/PlayerCacheSaveAllPlayersTask.java | 11 ++- prison-spigot/src/main/resources/config.yml | 72 +++++++++++++++---- 4 files changed, 91 insertions(+), 22 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 60447fc15..d284b4e89 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -14,7 +14,11 @@ These change logs represent the work that has been going on within prison. -# 3.3.0-alpha.15g 2023-11-04 +# 3.3.0-alpha.15g 2023-11-05 + + +* **Player Cache: Put some of the player cache numbers in to the config.yml file so they can be fine tuned if desired.** +See the changes to config.yml for information to what the new setting controls. * **GUI: Add support for changing the gui item names for Ranks and Mines. Ranks can now set their material type too.** diff --git a/prison-core/src/main/java/tech/mcprison/prison/cache/PlayerCache.java b/prison-core/src/main/java/tech/mcprison/prison/cache/PlayerCache.java index 67b1d3664..0875b92ad 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/cache/PlayerCache.java +++ b/prison-core/src/main/java/tech/mcprison/prison/cache/PlayerCache.java @@ -7,6 +7,7 @@ import java.util.SortedMap; import java.util.TreeMap; +import tech.mcprison.prison.Prison; import tech.mcprison.prison.internal.Player; import tech.mcprison.prison.internal.block.PrisonBlock.PrisonBlockType; import tech.mcprison.prison.internal.block.PrisonBlockStatusData; @@ -16,12 +17,19 @@ public class PlayerCache { - public static final String PLAYER_CACHE_WRITE_DELAY_CONFIG_NAME = "playercache.write_delay"; + public static final String PLAYER_CACHE_WRITE_DELAY_CONFIG_NAME = "player-cache.write-delay-sec"; + public static final int PLAYER_CACHE_WRITE_DELAY_VALUE_SEC = 60; // 60 seconds public static final long PLAYER_CACHE_WRITE_DELAY_VALUE_MS = 60000; // 60 seconds - public static final String PLAYER_CACHE_TIME_TO_LIVE_CONFIG_NAME = "playercache.time_to_live"; + public static final String PLAYER_CACHE_TIME_TO_LIVE_CONFIG_NAME = "player-cache.time-to-live-sec"; + public static final int PLAYER_CACHE_TIME_TO_LIVE_VALUE_SEC = 30 * 60; // 30 mins public static final long PLAYER_CACHE_TIME_TO_LIVE_VALUE_MS = 30 * 60 * 1000; // 30 mins + public static final String PLAYER_CACHE_UPDATE_PLAYER_STATS_CONFIG_NAME = "player-cache.update-player-stats-sec"; + public static final int PLAYER_CACHE_UPDATE_PLAYER_STATS_SEC = 30; // 30 Sec + + + private static PlayerCache instance; private PlayerCacheFiles cacheFiles; @@ -376,9 +384,13 @@ public PlayerCacheRunnable submitCacheRefresh() { PlayerCacheSaveAllPlayersTask task = new PlayerCacheSaveAllPlayersTask(); + long writeTimeTicks = Prison.get().getPlatform() + .getConfigInt( PLAYER_CACHE_WRITE_DELAY_CONFIG_NAME, + PLAYER_CACHE_WRITE_DELAY_VALUE_SEC ) * 20; + // Submit Timer Task to start running in 10 minutes (6000 ticks) and then // refresh stats every 5 minutes (3000 ticks): - int taskId = PrisonTaskSubmitter.runTaskTimerAsync( task, 6000, 3000 ); + int taskId = PrisonTaskSubmitter.runTaskTimerAsync( task, 6000, writeTimeTicks ); task.setTaskId( taskId ); return task; @@ -389,10 +401,14 @@ public PlayerCacheRunnable submitCacheUpdatePlayerStats() { PlayerCacheCheckTimersTask task = new PlayerCacheCheckTimersTask(); + int repeatTimeTicks = Prison.get().getPlatform() + .getConfigInt( PLAYER_CACHE_UPDATE_PLAYER_STATS_CONFIG_NAME, + PLAYER_CACHE_UPDATE_PLAYER_STATS_SEC ) * 20; + // Submit Timer Task to start running in 30 seconds (600 ticks) and then // refresh stats every 10 seconds (200 ticks). // This does not update any files or interacts with bukkit/spigot. - int taskId = PrisonTaskSubmitter.runTaskTimerAsync( task, 600, 200 ); + int taskId = PrisonTaskSubmitter.runTaskTimerAsync( task, 600, repeatTimeTicks ); task.setTaskId( taskId ); return task; diff --git a/prison-core/src/main/java/tech/mcprison/prison/cache/PlayerCacheSaveAllPlayersTask.java b/prison-core/src/main/java/tech/mcprison/prison/cache/PlayerCacheSaveAllPlayersTask.java index 0dd418f35..6f6c0c32e 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/cache/PlayerCacheSaveAllPlayersTask.java +++ b/prison-core/src/main/java/tech/mcprison/prison/cache/PlayerCacheSaveAllPlayersTask.java @@ -4,6 +4,7 @@ import java.util.List; import java.util.Set; +import tech.mcprison.prison.Prison; import tech.mcprison.prison.output.Output; /** @@ -45,7 +46,7 @@ public class PlayerCacheSaveAllPlayersTask extends PlayerCacheRunnable { - public static long LAST_SEEN_INTERVAL_30_MINUTES = 30 * 60 * 1000; +// public static long LAST_SEEN_INTERVAL_30_MINUTES = 30 * 60 * 1000; @Override public void run() @@ -55,6 +56,12 @@ public void run() List purge = new ArrayList<>(); + + long lastSeenInterval = Prison.get().getPlatform().getConfigInt( + PlayerCache.PLAYER_CACHE_TIME_TO_LIVE_CONFIG_NAME, + PlayerCache.PLAYER_CACHE_TIME_TO_LIVE_VALUE_SEC + ); + Set keys = pCache.getPlayers().keySet(); for ( String key : keys ) @@ -74,7 +81,7 @@ public void run() (playerData.isDirty() || playerData.getLastSeenDate() == 0 || (System.currentTimeMillis() - playerData.getLastSeenDate()) - > LAST_SEEN_INTERVAL_30_MINUTES ) ) { + > lastSeenInterval ) ) { // Update the player's last seen date only when dirty and they // are online: playerData.setLastSeenDate( System.currentTimeMillis() ); diff --git a/prison-spigot/src/main/resources/config.yml b/prison-spigot/src/main/resources/config.yml index f32cdc58a..4730ba395 100644 --- a/prison-spigot/src/main/resources/config.yml +++ b/prison-spigot/src/main/resources/config.yml @@ -279,21 +279,6 @@ storageType: "json" -# Hesitancy Delay Penalty - The purpose of the Hesitancy Delay Penalty is to encourage players -# to rankup to the next rank. Once a player exceeds the rankup cost, they start to incurr a -# rankup penalty. The penalty would be based upon the amount over the rankup cost. So if a player -# has 1.1 million, then only 0.1 million will be subject to the penalty and the penalty will be 20%. -# The max value a player can achieve for a rank will be the rankup cost, then the Hesitancy -# Delay Penalty will be subtracted from that amount. -# For example, if the rankup cost would be 1.0 million and a player has 1.1 million, then their -# max "score" they can achieve is 1.0 million, but the 20% penalty on the 0.1 million will be -# subtracted from the "score". So their adjusted score would be: -# 1.0 million - 0.1 million * 0.2 = 1.0 m - 20,000 = 0.8 m -# -top-stats: - rank-players: - hesitancy-delay-penalty: true - # Prison mines reset gap is the number of milliseconds that are used to # space out the mine resets when starting the server. This value should @@ -536,3 +521,60 @@ topNPlayers: interval-ticks: 6000 +# Hesitancy Delay Penalty - The purpose of the Hesitancy Delay Penalty is to encourage players +# to rankup to the next rank. Once a player exceeds the rankup cost, they start to incurr a +# rankup penalty. The penalty would be based upon the amount over the rankup cost. So if a player +# has 1.1 million, then only 0.1 million will be subject to the penalty and the penalty will be 20%. +# The max value a player can achieve for a rank will be the rankup cost, then the Hesitancy +# Delay Penalty will be subtracted from that amount. +# For example, if the rankup cost would be 1.0 million and a player has 1.1 million, then their +# max "score" they can achieve is 1.0 million, but the 20% penalty on the 0.1 million will be +# subtracted from the "score". So their adjusted score would be: +# 1.0 million - 0.1 million * 0.2 = 1.0 m - 20,000 = 0.8 m +# +top-stats: + rank-players: + hesitancy-delay-penalty: true + + + + + +# Player-Cache: The player cache stores and tracks a lot of detailed information for +# all players. There are a few settings that can help improve performance, or help +# adjust for your server's requiremments. +# write-delay-sec: Default 60 seconds - There is a player cache task that runs every +# x seconds, based upon this setting. It maintains the cache by +# saving 'dirty' entries, purging entries that have expired (off-line +# player cache entries that have been loaded for longer than the +# time to live value). etc... This task provides the house keeping +# functions, with the most critical aspect being saving changed cached +# entries. This value need to be carefully balanced to help ensure the +# entries are save frequently to protect against loss if the server +# crashes, but also it should be long enough so it does not consume +# too many resources. +# One minute may be a good starting point, but on stable servers, you +# could push it back to about 5 mins, 15 mins, or longer. +# When the server shuts down normally, all dirty entries in the cache +# are tried to be written before the server process is hard-terminated, +# so consideration need to be applied to how many changes can be saved +# before the server gives up and hard-terminates the saves, which could +# result in lost data. +# time-to-live-sec: Default 30 mins. For off line players, if there have been no +# interactions, or usage of their cache entries, they will be purged +# from the cache. This may also apply to online players too, but +# they would have to inactive for this duration. If a player is +# purged from cache, then they will be reloaded when the rejoin the +# server, or there is a need to update, or access their cache entry. +# update-player-stats-sec: Default 30 seconds. Checks to see if all players within the +# player cache who are marked as active are still online. +# This does not update any files and does not interact with +# bukkit/spigot. Very, very minimal impact on server, but +# important to recording player's activity level on the server. +player-cache: + write-delay-sec: 60 + time-to-live-sec: 1800 + update-player-stats-sec: 30 + + + \ No newline at end of file From 7fee122ecdbe071402e367d8be2d2cdab2ad1819 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sun, 5 Nov 2023 02:23:11 -0500 Subject: [PATCH 143/151] v3.3.0-alpha.15h 2023-11-05 --- docs/changelog_v3.3.x.md | 5 ++++- gradle.properties | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index d284b4e89..a9bd28adc 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -14,7 +14,10 @@ These change logs represent the work that has been going on within prison. -# 3.3.0-alpha.15g 2023-11-05 +# 3.3.0-alpha.15h 2023-11-05 + + +** 3.3.0-alpha.15h 2023-11-05** * **Player Cache: Put some of the player cache numbers in to the config.yml file so they can be fine tuned if desired.** diff --git a/gradle.properties b/gradle.properties index 3f422f4d5..aa000e5f9 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,7 +3,7 @@ ## # This is actually the "correct" place to define the version for the project. ## # Used within build.gradle with ${project.version}. ## # Can be overridden on the command line: gradle -Pversion=3.2.1-alpha.3 -version=3.3.0-alpha.15g +version=3.3.0-alpha.15h From 18b2817fcd74d544da3ff73f283964ef86516b4d Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sun, 12 Nov 2023 01:54:00 -0500 Subject: [PATCH 144/151] Block Converters: Change the usage to Player instead of RankPlayer since if ranks are disabled then RankPlayer could not exist. --- docs/changelog_v3.3.x.md | 5 ++++- .../autofeatures/BlockConvertersFileConfig.java | 16 ++++++++-------- .../spigot/autofeatures/AutoManagerFeatures.java | 9 +++++++-- 3 files changed, 19 insertions(+), 11 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index a9bd28adc..cf0215b7d 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -14,7 +14,10 @@ These change logs represent the work that has been going on within prison. -# 3.3.0-alpha.15h 2023-11-05 +# 3.3.0-alpha.15h 2023-11-12 + + +* **Block Converters: Change the usage to Player instead of RankPlayer since if ranks are disabled then RankPlayer could not exist.** ** 3.3.0-alpha.15h 2023-11-05** diff --git a/prison-core/src/main/java/tech/mcprison/prison/autofeatures/BlockConvertersFileConfig.java b/prison-core/src/main/java/tech/mcprison/prison/autofeatures/BlockConvertersFileConfig.java index 9aee09d88..14c28cb42 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/autofeatures/BlockConvertersFileConfig.java +++ b/prison-core/src/main/java/tech/mcprison/prison/autofeatures/BlockConvertersFileConfig.java @@ -10,9 +10,9 @@ import tech.mcprison.prison.autofeatures.AutoFeaturesFileConfig.AutoFeatures; import tech.mcprison.prison.file.JsonFileIO; import tech.mcprison.prison.internal.ItemStack; +import tech.mcprison.prison.internal.Player; import tech.mcprison.prison.internal.block.PrisonBlock; import tech.mcprison.prison.output.Output; -import tech.mcprison.prison.ranks.data.RankPlayer; public class BlockConvertersFileConfig { @@ -55,7 +55,7 @@ public BlockConvertersFileConfig() { } - public boolean processAutoFeaturesForBlock( RankPlayer player, String blockName ) { + public boolean processAutoFeaturesForBlock( Player player, String blockName ) { boolean results = isProcessAutoFeaturesAllBlocks( player ); if ( !results ) { @@ -65,7 +65,7 @@ public boolean processAutoFeaturesForBlock( RankPlayer player, String blockName return results; } - public BlockConverterResults getBlockConverterItemStacks( RankPlayer player, + public BlockConverterResults getBlockConverterItemStacks( Player player, String blockName, int blockQuantity, BlockConverterTypes bcType ) { @@ -126,7 +126,7 @@ public BlockConverterResults getBlockConverterItemStacks( RankPlayer player, * @param blockName * @return */ - public BlockConverter getBlockConverter( RankPlayer player, String blockName, + public BlockConverter getBlockConverter( Player player, String blockName, BlockConverterTypes bcType ) { BlockConverter results = null; @@ -194,7 +194,7 @@ public BlockConverter getBlockConverter( String blockName, BlockConverterTypes b * @param bc * @return */ - private List getBlockConverterOutputs(RankPlayer player, BlockConverter bc) { + private List getBlockConverterOutputs(Player player, BlockConverter bc) { List outputs = new ArrayList<>(); @@ -202,7 +202,7 @@ private List getBlockConverterOutputs(RankPlayer player, B for ( BlockConverterOutput bcOutput : bc.getOutputs() ) { - if ( bcOutput.isEnabled() ) { + if ( bcOutput.isEnabled() ) { // If chance, and the random number is greater than the chance, then skip this output: if ( bcOutput.getChance() != null && @@ -253,7 +253,7 @@ private List getBlockConverterOutputs(RankPlayer player, B * @param player * @return */ - public Boolean isProcessAutoFeaturesAllBlocks( RankPlayer player ) { + public Boolean isProcessAutoFeaturesAllBlocks( Player player ) { if ( !getBcData().getProcessAutoFeaturesAllBlocks().containsKey( player.getName() ) ) { BlockConverterResults allBlocksBCR = getBlockConverterItemStacks( player, "*all*", 1, BlockConverterTypes.autoPickupFeatures ); @@ -381,7 +381,7 @@ public void setBcData(BlockConvertersData bcData) { * @param blockName * @return */ - public List findEventTrigger(RankPlayer rPlayer, String blockName) { + public List findEventTrigger( Player rPlayer, String blockName) { List eventTriggers = null; BlockConverterEventTrigger bcet = (BlockConverterEventTrigger) diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerFeatures.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerFeatures.java index ca7d99f08..9b1666f51 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerFeatures.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerFeatures.java @@ -3274,11 +3274,16 @@ public boolean checkBlockConverterEventTrigger(PrisonMinesBlockBreakEvent pmEven long start = System.currentTimeMillis(); - RankPlayer rPlayer = PrisonRanks.getInstance().getPlayerManager().getPlayer( pmEvent.getSpigotPlayer() ); + if ( PrisonRanks.getInstance().isEnabled() ) { + + } + + SpigotPlayer sPlayer = pmEvent.getSpigotPlayer(); +// RankPlayer rPlayer = PrisonRanks.getInstance().getPlayerManager().getPlayer( pmEvent.getSpigotPlayer() ); String blockName = pmEvent.getSpigotBlock().getBlockName(); List eventTriggers = - AutoFeaturesWrapper.getBlockConvertersInstance().findEventTrigger( rPlayer, blockName ); + AutoFeaturesWrapper.getBlockConvertersInstance().findEventTrigger( sPlayer, blockName ); if ( eventTriggers != null ) { StringBuilder sb = new StringBuilder(); From 021b451b5e0a26af0c8d3aa3f04d73b39ad77290 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sun, 12 Nov 2023 02:20:30 -0500 Subject: [PATCH 145/151] Economy support for CoinsEngine: support has been initially added, but it is unsure if it is working correctly. This request originated from pingu and they said it's not working, but has not provided any more information. Unsure how it's not working, or if they cannot use it the way they originally envisioned because sellall cannot support different currencies for different items within sellall. Because of the lack of an API jar to be used, a new sub-project 'prison-misc' was created to be able to generate a pseudo-shell api for the CoinsEngine plugin. This pseduo api jar is used strictly to allow the successful compiling of the prison's economy hooks for CoinsEngine. --- docs/changelog_v3.3.x.md | 4 + prison-misc/build.gradle | 91 +++++++ .../coinsengine/api/CoinsEngineAPI.java | 72 ++++++ .../coinsengine/api/currency/Currency.java | 88 +++++++ .../lib/CoinsEngine pseudo API not-real.jar | Bin 0 -> 2570 bytes .../spigot/economies/CoinsEngineEconomy.java | 240 ++++++++++++++++++ .../economies/CoinsEngineEconomyWrapper.java | 108 ++++++++ settings.gradle | 1 + 8 files changed, 604 insertions(+) create mode 100644 prison-misc/build.gradle create mode 100644 prison-misc/src/main/java/su/nightexpress/coinsengine/api/CoinsEngineAPI.java create mode 100644 prison-misc/src/main/java/su/nightexpress/coinsengine/api/currency/Currency.java create mode 100644 prison-spigot/lib/CoinsEngine pseudo API not-real.jar create mode 100644 prison-spigot/src/main/java/tech/mcprison/prison/spigot/economies/CoinsEngineEconomy.java create mode 100644 prison-spigot/src/main/java/tech/mcprison/prison/spigot/economies/CoinsEngineEconomyWrapper.java diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index cf0215b7d..ad437a5ba 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -17,6 +17,10 @@ These change logs represent the work that has been going on within prison. # 3.3.0-alpha.15h 2023-11-12 +* **Economy support for CoinsEngine: support has been initially added**, but it is unsure if it is working correctly. This request originated from pingu and they said it's not working, but has not provided any more information. Unsure how it's not working, or if they cannot use it the way they originally envisioned because sellall cannot support different currencies for different items within sellall. +Because of the lack of an API jar to be used, a new sub-project 'prison-misc' was created to be able to generate a pseudo-shell api for the CoinsEngine plugin. This pseduo api jar is used strictly to allow the successful compiling of the prison's economy hooks for CoinsEngine. + + * **Block Converters: Change the usage to Player instead of RankPlayer since if ranks are disabled then RankPlayer could not exist.** diff --git a/prison-misc/build.gradle b/prison-misc/build.gradle new file mode 100644 index 000000000..5d17da6d5 --- /dev/null +++ b/prison-misc/build.gradle @@ -0,0 +1,91 @@ +/* + * Prison is a Minecraft plugin for the prison game mode. + * Copyright (C) 2017 The Prison Team + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +group 'tech.mcprison' + +apply plugin: 'java' + +compileJava.options.encoding = 'UTF-8' +compileTestJava.options.encoding = "UTF-8" + +//sourceCompatibility = 1.8 + + +// https://www.spigotmc.org/wiki/spigot-gradle/ + + +repositories { + mavenCentral() + + + maven { + url = 'https://hub.spigotmc.org/nexus/content/repositories/snapshots/' + + // As of Gradle 5.1, you can limit this to only those + // dependencies you expect from it + content { + includeGroup 'org.bukkit' + includeGroup 'org.spigotmc' + } + } + /* + As Spigot-API depends on the BungeeCord ChatComponent-API, + we need to add the Sonatype OSS repository, as Gradle, + in comparison to maven, doesn't want to understand the ~/.m2 + directory unless added using mavenLocal(). Maven usually just gets + it from there, as most people have run the BuildTools at least once. + This is therefore not needed if you're using the full Spigot/CraftBukkit, + or if you're using the Bukkit API. + */ + maven { url = 'https://oss.sonatype.org/content/repositories/snapshots' } + maven { url = 'https://oss.sonatype.org/content/repositories/central' } + + // mavenLocal() // This is needed for CraftBukkit and Spigot. + maven { + url "https://mvnrepository.com/artifact" + } + + // maven { url = "https://hub.spigotmc.org/nexus/content/groups/public" } + + + // maven { url = "https://maven.enginehub.org/repo/" } +} + + + +dependencies { +// implementation project(':prison-core') +// implementation project(':prison-mines') +// implementation project(':prison-ranks') +// implementation project(':prison-sellall') + + + // https://mvnrepository.com/artifact/org.jetbrains/annotations + implementation 'org.jetbrains:annotations:24.0.1' + + + compileOnly 'org.spigotmc:spigot-api:1.13.2-R0.1-SNAPSHOT' + + + + testImplementation group: 'junit', name: 'junit', version: '4.12' + +} + + + diff --git a/prison-misc/src/main/java/su/nightexpress/coinsengine/api/CoinsEngineAPI.java b/prison-misc/src/main/java/su/nightexpress/coinsengine/api/CoinsEngineAPI.java new file mode 100644 index 000000000..70bac8065 --- /dev/null +++ b/prison-misc/src/main/java/su/nightexpress/coinsengine/api/CoinsEngineAPI.java @@ -0,0 +1,72 @@ +package su.nightexpress.coinsengine.api; + +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import su.nightexpress.coinsengine.api.currency.Currency; + +public class CoinsEngineAPI { + + //public static final CoinsEngine PLUGIN = CoinsEngine.getPlugin(CoinsEngine.class); + + public static double getBalance(@NotNull Player player, @NotNull Currency currency) { + return 0d; + } + + public static void addBalance(@NotNull Player player, @NotNull Currency currency, double amount) { + + } + + public static void setBalance(@NotNull Player player, @NotNull Currency currency, double amount) { + + } + + public static void removeBalance(@NotNull Player player, @NotNull Currency currency, double amount) { + + } + +// @NotNull +// public static CoinsUser getUserData(@NotNull Player player) { +// return PLUGIN.getUserManager().getUserData(player); +// } +// +// @Nullable +// public static CoinsUser getUserData(@NotNull String name) { +// return PLUGIN.getUserManager().getUserData(name); +// } +// +// @NotNull +// public static CompletableFuture getUserDataAsync(@NotNull String name) { +// return PLUGIN.getUserManager().getUserDataAsync(name); +// } +// +// @Nullable +// public static CoinsUser getUserData(@NotNull UUID uuid) { +// return PLUGIN.getUserManager().getUserData(uuid); +// } +// +// @NotNull +// public static CompletableFuture getUserDataAsync(@NotNull UUID uuid) { +// return PLUGIN.getUserManager().getUserDataAsync(uuid); +// } + + @Nullable + public static Currency getCurrency(@NotNull String id) { + return null; + } + + public static boolean hasCurrency(@NotNull String id) { + return false; + } + +// @NotNull +// public static UserManager getUserManager() { +// return PLUGIN.getUserManager(); +// } +// +// @NotNull +// public static CurrencyManager getCurrencyManager() { +// return PLUGIN.getCurrencyManager(); +// } +} diff --git a/prison-misc/src/main/java/su/nightexpress/coinsengine/api/currency/Currency.java b/prison-misc/src/main/java/su/nightexpress/coinsengine/api/currency/Currency.java new file mode 100644 index 000000000..0123349c8 --- /dev/null +++ b/prison-misc/src/main/java/su/nightexpress/coinsengine/api/currency/Currency.java @@ -0,0 +1,88 @@ +package su.nightexpress.coinsengine.api.currency; + +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.NotNull; + +public interface Currency { + + default boolean isUnlimited() { + return true; + } + + default boolean isLimited() { + return false; + } + + default boolean isInteger() { + return false; + } + + default double fine(double amount) { + return 0d; + } + + default double limit(double amount) { + return 0d; + } + + default double fineAndLimit(double amount) { + return 0d; + } + + @NotNull + default String getPermission() { + return ""; + } + + @NotNull + default String formatValue(double balance) { + return ""; + } + + @NotNull + default String format(double balance) { + return ""; + } + + @NotNull String getId(); + + @NotNull String getName(); + + //void setName(@NotNull String name); + + @NotNull String getSymbol(); + + @NotNull String getFormat(); + + //void setSymbol(@NotNull String symbol); + + @NotNull String[] getCommandAliases(); + + @NotNull ItemStack getIcon(); + + //void setCommandAliases(@NotNull String... aliases); + + boolean isDecimal(); + + //void setDecimal(boolean decimal); + + boolean isPermissionRequired(); + + //void setPermissionRequired(boolean permissionRequired); + + boolean isTransferAllowed(); + + double getMinTransferAmount(); + + //void setTransferAllowed(boolean transferAllowed); + + double getStartValue(); + + //void setStartValue(double startValue); + + double getMaxValue(); + + //void setMaxValue(double maxValue); + + boolean isVaultEconomy(); +} diff --git a/prison-spigot/lib/CoinsEngine pseudo API not-real.jar b/prison-spigot/lib/CoinsEngine pseudo API not-real.jar new file mode 100644 index 0000000000000000000000000000000000000000..31eebc6c2c4af62f509ada0fb7faf594ad94ac37 GIT binary patch literal 2570 zcmWIWW@h1HVBp|j2%a4p&Hw~VAOZ+Df!NnI#8KDN&rP41ApovWm;ZIxrh2A#(m(~0 zKrDi+(AUw=)6F$FM9UV3I;Dqg(`1oS2rWMb$KzWnT4 z8ZZ=V*ccd0h|up0a*He2Esg=6ddWG7#l>4E-}e`G6gZx~ZfUDn#=<`V0gjHk$2O=* zB?m1!xTtN(%1|EueYxvrmo2=T{q0-F-}ydQ)P?2$F#lQHv-$MROI$*oCOhW>!Ta>` zvR{v%Z-3A5f#Y480^{q<9dp~PIacbfTvFLJK_l;tvdU>kXN4zPL7iDwR&xLCyMB9% zQ8Z`Gy?f82qU_^*W=-P}lnXi3p?Nb$^5eqQt`bJ}6SPEDd202Pt7=F8Z~eSId$($f zPwg2|(STrx^M%r&@-o(l+Zq7?1|3}YVd170lr^@X| z4t9#5{9*XMt4^VY+5F(*{fqxD zWn8P(tNBSHQpLLLz4im~SruCtHB!XY6XqN{`Iz@f>Yb=*VM2O84c~stIrnAx#50-G zcNWOBYJNI+wrIlgA3SG2KhT{pb7|}g9+4NbKWXI5eO$=&EWxhLcCmh@^5W$>7S~qo zmirbdvH497qnPI7oGd* z?E?Y>GDRaKWotjIbWUAnywysi^1|{rW>XI2HF=7?tS@q#U;Bam$6}fMZP8s@omX3L z-nrBK`JCSq|NQy-mz}|;{jKMXQ%$p5m$MYb>=$R`-} zTjhd(U*R^`6foV6mv6a)AC4-}-d#B5MH%*L~ttn#bA~q{%YmDlIg$sLH6df+i>{zX8kgOs&bOTWUqB4fAj;vE^uho0JsJW^cUX}r$TEI`mnDr-Ws@0zPi zvvwapQ_+?5QSYt%F5XP3K!F9vPAxcA_xy|h+&c?H6iwMpIyQ8>zDbJEjqFc4;O?@l z`}ngB-BRb2y0rz z)%tu6s;o1<8~kP2!LZ4{XTRhz`s_T@IN5;Pd1mDd-x>Oo^ny0Wv(M-@EaptEU3T~E z!J0X14cd;K6_nym&bTAFu#mUw#1^U9Cq?G4e#&)7`FcrWj!TN6Wvo-R?0-)M*A81I z^9^6tz3~1r=i#E))3u8Aw2B{u#oP@2bo%j${6F(+W*x|t@qFcVWbVX{-O7U6%7Wh? z{1Z50qQvpVVD$zwr>Bf|#o6*|-vX1aFBG|5lq9eIt<%I^9OPbjQHpLXdQl29cuAuh3kk-e7OVl@tiX~P Q)WYLrmIf GemsEconomy is registered, always hook this up because this may be needed + * to be used instead of the primary economy if they are using a custom currency. + *

+ */ + @Override + public void integrate() { + addDebugInfo( "1" ); + if ( isRegistered()) { + addDebugInfo( "2" ); + try { + addDebugInfo( "3" ); + this.wrapper = new CoinsEngineEconomyWrapper(); + addDebugInfo( "4" ); + } + catch ( java.lang.NoClassDefFoundError | Exception e ) { + addDebugInfo( "5:Exception:" + e.getMessage() ); + e.printStackTrace(); + } + } + addDebugInfo( "6" ); + } + + + @Override + public boolean supportedCurrency( String currencyName ) { + boolean supported = false; + + if ( wrapper != null ) { + supported = wrapper.supportedCurrency( currencyName ); + } + + return supported; + } + + @Override + public double getBalance(Player player) { + double amount = 0; + if ( wrapper != null ) { + + synchronized ( wrapper ) { + amount = wrapper.getBalance(player); + } + } + return amount; + } + + @Override + public double getBalance(Player player, String currencyName) { + double amount = 0; + if ( wrapper != null ) { + + synchronized ( wrapper ) { + amount = wrapper.getBalance(player, currencyName); + } + } + return amount; + } + + @Override + public boolean setBalance(Player player, double amount) { + boolean results = false; + + if ( wrapper != null ) { + synchronized ( wrapper ) { + + double bal = getBalance(player); + double remainder = amount - bal; + + if ( remainder > 0 ) { + wrapper.addBalance( player, remainder ); + } + else if ( remainder < 0 ) { + wrapper.withdraw( player, (remainder * -1) ); + } + double balResults = getBalance(player); + + results = balResults == amount; + } + } + return results; + } + + @Override + public boolean setBalance(Player player, double amount, String currencyName) { + boolean results = false; + + if ( wrapper != null ) { + + synchronized ( wrapper ) { + + double bal = getBalance(player, currencyName); + double remainder = amount - bal; + + if ( remainder > 0 ) { + wrapper.addBalance( player, remainder, currencyName ); + } + else if ( remainder < 0 ) { + wrapper.withdraw( player, (remainder * -1), currencyName ); + } + double balResults = getBalance(player, currencyName); + + results = balResults == amount; + } + } + return results; + } + + @Override + public boolean addBalance(Player player, double amount) { + boolean results = false; + + if ( wrapper != null ) { + + synchronized ( wrapper ) { + + double bal = getBalance(player); + wrapper.addBalance(player, amount); + double balResults = getBalance(player); + + results = balResults == amount + bal; + } + } + + return results; + } + + @Override + public boolean addBalance(Player player, double amount, String currencyName) { + boolean results = false; + + if ( wrapper != null ) { + + synchronized ( wrapper ) { + + double bal = getBalance(player, currencyName); + wrapper.addBalance(player, amount, currencyName); + double balResults = getBalance(player, currencyName); + + results = balResults == amount + bal; + } + } + + return results; + } + + @Override + public boolean removeBalance(Player player, double amount) { + boolean results = false; + + if ( wrapper != null ) { + synchronized ( wrapper ) { + + double bal = getBalance(player); + wrapper.withdraw(player, amount); + double balResults = getBalance(player); + + results = balResults == bal - amount; + } + } + + return results; + } + + @Override + public boolean removeBalance(Player player, double amount, String currencyName) { + boolean results = false; + + if ( wrapper != null ) { + synchronized ( wrapper ) { + + double bal = getBalance(player, currencyName); + wrapper.withdraw(player, amount, currencyName); + double balResults = getBalance(player, currencyName); + + results = balResults == bal - amount; + } + } + + return results; + } + + @Override + public boolean canAfford(Player player, double amount) { + boolean results = false; + if ( wrapper != null ) { + results = getBalance(player) >= amount; + } + return results; + } + + @Override + public boolean canAfford(Player player, double amount, String currencyName) { + boolean results = false; + if ( wrapper != null ) { + results = getBalance(player, currencyName) >= amount; + } + return results; + } + + @Override + public boolean hasIntegrated() { + return wrapper != null && wrapper.isEnabled(); + } + + @Override + public void disableIntegration() { + wrapper = null; + } + + @Override + public String getDisplayName() + { + return super.getDisplayName() + + ( availableAsAnAlternative ? " (disabled)" : ""); + } + + @Override + public String getPluginSourceURL() { + return "https://www.spigotmc.org/resources/coinsengine-economy-and-virtual-currencies.84121/"; + } + + +} diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/economies/CoinsEngineEconomyWrapper.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/economies/CoinsEngineEconomyWrapper.java new file mode 100644 index 000000000..e1d248e57 --- /dev/null +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/economies/CoinsEngineEconomyWrapper.java @@ -0,0 +1,108 @@ +package tech.mcprison.prison.spigot.economies; + +import su.nightexpress.coinsengine.api.CoinsEngineAPI; +import su.nightexpress.coinsengine.api.currency.Currency; +import tech.mcprison.prison.internal.Player; +import tech.mcprison.prison.output.Output; +import tech.mcprison.prison.spigot.game.SpigotPlayer; + +public class CoinsEngineEconomyWrapper { + + private CoinsEngineAPI economy; + + public CoinsEngineEconomyWrapper() { + super(); + + + try { + this.economy = new CoinsEngineAPI(); + } + catch (Exception e) { + // If CoinsEngineAPI does not exist, then ignore this exception: + } + + + } + + + public boolean isEnabled() { + return economy != null; + } + + public boolean supportedCurrency( String currencyName ) { + boolean supported = ( getCurrency( currencyName ) != null ); + + return supported; + } + + + public Currency getCurrency( String currencyNamme ) { + return CoinsEngineAPI.getCurrency( currencyNamme ); + } + + + public double getBalance(Player player) { + + Output.get().logWarn( "CoinsEngineEconomy getBalance() - Fail: MUST include a currencyName."); + return getBalance(player, null); + } + + public double getBalance(Player player, String currencyName) { + double results = 0; + if (economy != null && player instanceof SpigotPlayer ) { + + org.bukkit.entity.Player sPlayer = ((SpigotPlayer) player).getWrapper(); + + Currency currency = getCurrency( currencyName ); + if ( currency != null && sPlayer != null) { + + results = CoinsEngineAPI.getBalance( sPlayer, currency ); + } + } + return results; + } + + public void addBalance(Player player, double amount) { + + Output.get().logWarn( "CoinsEngineEconomy addBalance() - Fail: MUST include a currencyName."); + addBalance(player, amount, null); + } + + public void addBalance(Player player, double amount, String currencyName) { + + if (economy != null && player instanceof SpigotPlayer ) { + + org.bukkit.entity.Player sPlayer = ((SpigotPlayer) player).getWrapper(); + + Currency currency = getCurrency( currencyName ); + if ( currency != null && sPlayer != null) { + + CoinsEngineAPI.addBalance( sPlayer, currency, amount ); + } + } + } + + + public void withdraw(Player player, double amount) { + + Output.get().logWarn( "CoinsEngineEconomy withdraw() - Fail: MUST include a currencyName."); + withdraw(player, amount, null); + } + + public void withdraw(Player player, double amount, String currencyName) { + + + if (economy != null && player instanceof SpigotPlayer ) { + + org.bukkit.entity.Player sPlayer = ((SpigotPlayer) player).getWrapper(); + + Currency currency = getCurrency( currencyName ); + if ( currency != null && sPlayer != null) { + + CoinsEngineAPI.removeBalance( sPlayer, currency, amount ); + } + } + + } + +} diff --git a/settings.gradle b/settings.gradle index d12bb3e21..7b7f2ca03 100644 --- a/settings.gradle +++ b/settings.gradle @@ -25,6 +25,7 @@ include 'prison-mines' include 'prison-ranks' include 'prison-sellall' +include 'prison-misc' include 'prison-worldguard6' include 'prison-worldguard7' From 2ff0cd4c48c01b3de3875dcba2d3d21aef4f8b42 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sun, 12 Nov 2023 02:24:57 -0500 Subject: [PATCH 146/151] Economy support for CoinsEngine: support has been initially added, but it is unsure if it is working correctly. This request originated from pingu and they said it's not working, but has not provided any more information. Unsure how it's not working, or if they cannot use it the way they originally envisioned because sellall cannot support different currencies for different items within sellall. Because of the lack of an API jar to be used, a new sub-project 'prison-misc' was created to be able to generate a pseudo-shell api for the CoinsEngine plugin. This pseduo api jar is used strictly to allow the successful compiling of the prison's economy hooks for CoinsEngine. --- .../src/main/java/tech/mcprison/prison/spigot/SpigotPrison.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/SpigotPrison.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/SpigotPrison.java index cecaf3cf5..1945db12c 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/SpigotPrison.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/SpigotPrison.java @@ -81,6 +81,7 @@ import tech.mcprison.prison.spigot.configs.MessagesConfig; import tech.mcprison.prison.spigot.configs.SellAllConfig; import tech.mcprison.prison.spigot.customblock.CustomItems; +import tech.mcprison.prison.spigot.economies.CoinsEngineEconomy; import tech.mcprison.prison.spigot.economies.EssentialsEconomy; import tech.mcprison.prison.spigot.economies.GemsEconomy; import tech.mcprison.prison.spigot.economies.SaneEconomy; @@ -943,6 +944,7 @@ private void initIntegrations() { registerIntegration(new EssentialsEconomy()); registerIntegration(new SaneEconomy()); registerIntegration(new GemsEconomy()); + registerIntegration(new CoinsEngineEconomy()); registerIntegration(new VaultPermissions()); registerIntegration(new LuckPerms5()); From 97c5946b54e6c507a76e9df7e437c0cc1257b0d9 Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Thu, 16 Nov 2023 13:15:12 -0500 Subject: [PATCH 147/151] Sellall: Standardize how sellall is being checked to see if it's enabled. There are still a few ways it can be improved, but this is a step in the right direction. There was a problem with the older way things were being handled that was causing an NPE with the SpigotPlayer, which was brought to my attention by DinoFengz, but I noticed there were other problems that needed to also be addressed. --- docs/changelog_v3.3.x.md | 7 +- .../api/PrisonMinesBlockBreakEvent.java | 52 +++--- .../autofeatures/AutoManagerFeatures.java | 7 +- .../events/AutoManagerBlockBreakEvents.java | 88 ++++----- .../spigot/block/OnBlockBreakEventCore.java | 38 ++-- .../PrisonSpigotGUISellAllCommands.java | 5 +- .../commands/PrisonSpigotSellAllCommands.java | 174 +++++++----------- .../prison/spigot/game/SpigotPlayer.java | 42 ++--- 8 files changed, 191 insertions(+), 222 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index ad437a5ba..486ffe94e 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -14,7 +14,12 @@ These change logs represent the work that has been going on within prison. -# 3.3.0-alpha.15h 2023-11-12 +# 3.3.0-alpha.15h 2023-11-16 + + +* **Sellall: Standardize how sellall is being checked to see if it's enabled.** +There are still a few ways it can be improved, but this is a step in the right direction. +There was a problem with the older way things were being handled that was causing an NPE with the SpigotPlayer, which was brought to my attention by DinoFengz, but I noticed there were other problems that needed to also be addressed. * **Economy support for CoinsEngine: support has been initially added**, but it is unsure if it is working correctly. This request originated from pingu and they said it's not working, but has not provided any more information. Unsure how it's not working, or if they cannot use it the way they originally envisioned because sellall cannot support different currencies for different items within sellall. diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/api/PrisonMinesBlockBreakEvent.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/api/PrisonMinesBlockBreakEvent.java index ce5283bbd..d20bf0304 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/api/PrisonMinesBlockBreakEvent.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/api/PrisonMinesBlockBreakEvent.java @@ -16,6 +16,7 @@ import tech.mcprison.prison.mines.data.Mine; import tech.mcprison.prison.mines.features.MineBlockEvent.BlockEventType; import tech.mcprison.prison.output.Output; +import tech.mcprison.prison.spigot.SpigotPrison; import tech.mcprison.prison.spigot.block.BlockBreakPriority; import tech.mcprison.prison.spigot.block.SpigotBlock; import tech.mcprison.prison.spigot.block.SpigotItemStack; @@ -332,32 +333,35 @@ public void performSellAllOnPlayerInventoryLogged( String description ) { } public String performSellAllOnPlayerInventoryString( String description ) { - - final long nanoStart = System.nanoTime(); - - boolean isUsingSign = false; - boolean completelySilent = false; - boolean notifyPlayerEarned = false; - boolean notifyPlayerDelay = false; - boolean notifyPlayerEarningDelay = true; - boolean playSoundOnSellAll = false; - boolean notifyNothingToSell = false; - - boolean success = SellAllUtil.get().sellAllSell( getPlayer(), - isUsingSign, completelySilent, - notifyPlayerEarned, notifyPlayerDelay, - notifyPlayerEarningDelay, playSoundOnSellAll, - notifyNothingToSell, null ); - final long nanoStop = System.nanoTime(); - double milliTime = (nanoStop - nanoStart) / 1000000d; - - DecimalFormat dFmt = Prison.get().getDecimalFormat("#,##0.00"); StringBuilder sb = new StringBuilder(); - sb.append( "(" ) - .append( description) - .append( ": " + (success ? "success" : "failed")) - .append( " ms: " + dFmt.format( milliTime ) + ") "); + if ( SpigotPrison.getInstance().isSellAllEnabled() ) { + + final long nanoStart = System.nanoTime(); + + boolean isUsingSign = false; + boolean completelySilent = false; + boolean notifyPlayerEarned = false; + boolean notifyPlayerDelay = false; + boolean notifyPlayerEarningDelay = true; + boolean playSoundOnSellAll = false; + boolean notifyNothingToSell = false; + + boolean success = SellAllUtil.get().sellAllSell( getPlayer(), + isUsingSign, completelySilent, + notifyPlayerEarned, notifyPlayerDelay, + notifyPlayerEarningDelay, playSoundOnSellAll, + notifyNothingToSell, null ); + final long nanoStop = System.nanoTime(); + double milliTime = (nanoStop - nanoStart) / 1000000d; + + DecimalFormat dFmt = Prison.get().getDecimalFormat("#,##0.00"); + + sb.append( "(" ) + .append( description) + .append( ": " + (success ? "success" : "failed")) + .append( " ms: " + dFmt.format( milliTime ) + ") "); + } return sb.toString(); } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerFeatures.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerFeatures.java index 9b1666f51..56a89af86 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerFeatures.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerFeatures.java @@ -888,8 +888,7 @@ protected int autoPickup( PrisonMinesBlockBreakEvent pmEvent, long nanoTime = 0L; - boolean isSellallEnabled = SellAllUtil.get() != null && - SpigotPrison.getInstance().isSellAllEnabled(); + boolean isSellallEnabled = SpigotPrison.getInstance().isSellAllEnabled(); // boolean isPlayerAutoSellTurnedOff = SellAllUtil.get().isAutoSellPerUserToggleable && @@ -1202,7 +1201,7 @@ public int calculateNormalDrop( PrisonMinesBlockBreakEvent pmEvent ) { count += itemStack.getAmount(); // Since this is not auto pickup, then only autosell if set in the pmEvent: - if ( pmEvent.isForceAutoSell() && SellAllUtil.get() != null ) { + if ( pmEvent.isForceAutoSell() && SpigotPrison.getInstance().isSellAllEnabled() ) { Player player = pmEvent.getPlayer(); @@ -1227,7 +1226,7 @@ public int calculateNormalDrop( PrisonMinesBlockBreakEvent pmEvent ) { pmEvent.getDebugInfo().append( "(dropping: " + itemStack.getName() + " qty: " + itemStack.getAmount() ); - if ( SellAllUtil.get() != null ) { + if ( SpigotPrison.getInstance().isSellAllEnabled() ) { double amount = SellAllUtil.get().sellAllSell( player, itemStack, true, false, false ); autosellTotal += amount; diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerBlockBreakEvents.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerBlockBreakEvents.java index 3fecf1bd8..c5726ea9f 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerBlockBreakEvents.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerBlockBreakEvents.java @@ -501,65 +501,65 @@ else if ( cancelBy == EventListenerCancelBy.drops ) { // debugInfo.append( "(logic bypass) " ); // } - } - - - boolean isPlayerAutosellEnabled = pmEvent.getSpigotPlayer().isAutoSellEnabled( pmEvent.getDebugInfo() ); - - + + boolean isPlayerAutosellEnabled = pmEvent.getSpigotPlayer().isAutoSellEnabled( pmEvent.getDebugInfo() ); + + // // In the event, forceAutoSell is enabled, which means the drops must be sold. // // The player's toggle cannot disable this. // boolean forceAutoSell = isSellallEnabled && pmEvent.isForceAutoSell(); // - + // // AutoFeature's autosell per block break - global setting // boolean autoSellBySettings = // isPlayerAutosellEnabled && // isBoolean(AutoFeatures.isAutoSellPerBlockBreakEnabled); - - - boolean isPlayerAutoSellByPerm = pmEvent.getSpigotPlayer().isAutoSellByPermEnabled( isPlayerAutosellEnabled ); - - - - - if ( isBoolean( AutoFeatures.isForceSellAllOnInventoryWhenBukkitBlockBreakEventFires ) && - ( isPlayerAutosellEnabled || isPlayerAutoSellByPerm )) { - - pmEvent.getDebugInfo().append( Output.get().getColorCodeWarning()); - pmEvent.performSellAllOnPlayerInventoryLogged( "FORCED BlockBreakEvent sellall"); - pmEvent.getDebugInfo().append( Output.get().getColorCodeDebug()); - } - - if ( isBoolean( AutoFeatures.isEnabledDelayedSellAllOnInventoryWhenBukkitBlockBreakEventFires ) && - ( isPlayerAutosellEnabled || isPlayerAutoSellByPerm ) ) { - if ( !getDelayedSellallPlayers().contains( pmEvent.getSpigotPlayer() ) ) { - - getDelayedSellallPlayers().add( pmEvent.getSpigotPlayer() ); - - int ticks = getInteger( AutoFeatures.isEnabledDelayedSellAllOnInventoryDelayInTicks ); + + boolean isPlayerAutoSellByPerm = pmEvent.getSpigotPlayer().isAutoSellByPermEnabled( isPlayerAutosellEnabled ); + + + + + if ( isBoolean( AutoFeatures.isForceSellAllOnInventoryWhenBukkitBlockBreakEventFires ) && + ( isPlayerAutosellEnabled || isPlayerAutoSellByPerm )) { - pmEvent.getDebugInfo().append( Output.get().getColorCodeError()); - pmEvent.getDebugInfo().append( "(BlockBreakEvent delayed sellall submitted: no details available, see sellall debug info) " ); + pmEvent.getDebugInfo().append( Output.get().getColorCodeWarning()); + pmEvent.performSellAllOnPlayerInventoryLogged( "FORCED BlockBreakEvent sellall"); pmEvent.getDebugInfo().append( Output.get().getColorCodeDebug()); + } + + if ( isBoolean( AutoFeatures.isEnabledDelayedSellAllOnInventoryWhenBukkitBlockBreakEventFires ) && + ( isPlayerAutosellEnabled || isPlayerAutoSellByPerm ) ) { - final PrisonMinesBlockBreakEvent pmEventFinal = pmEvent; - - new BukkitRunnable() { - @Override - public void run() { - - String message = pmEventFinal.performSellAllOnPlayerInventoryString("delayed sellall"); - getDelayedSellallPlayers().remove( pmEventFinal.getSpigotPlayer() ); - - Output.get().logDebug(message); - } - }.runTaskLater( SpigotPrison.getInstance(), ticks ); + if ( !getDelayedSellallPlayers().contains( pmEvent.getSpigotPlayer() ) ) { + + getDelayedSellallPlayers().add( pmEvent.getSpigotPlayer() ); + + int ticks = getInteger( AutoFeatures.isEnabledDelayedSellAllOnInventoryDelayInTicks ); + + pmEvent.getDebugInfo().append( Output.get().getColorCodeError()); + pmEvent.getDebugInfo().append( "(BlockBreakEvent delayed sellall submitted: no details available, see sellall debug info) " ); + pmEvent.getDebugInfo().append( Output.get().getColorCodeDebug()); + + final PrisonMinesBlockBreakEvent pmEventFinal = pmEvent; + + new BukkitRunnable() { + @Override + public void run() { + + String message = pmEventFinal.performSellAllOnPlayerInventoryString("delayed sellall"); + getDelayedSellallPlayers().remove( pmEventFinal.getSpigotPlayer() ); + + Output.get().logDebug(message); + } + }.runTaskLater( SpigotPrison.getInstance(), ticks ); + } } + + printDebugInfo( pmEvent, start ); } - printDebugInfo( pmEvent, start ); } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/block/OnBlockBreakEventCore.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/block/OnBlockBreakEventCore.java index 7fe0d5c57..3017e4ec4 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/block/OnBlockBreakEventCore.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/block/OnBlockBreakEventCore.java @@ -915,27 +915,26 @@ else if ( results && pmEvent.getBbPriority().isMonitor() && mine != null ) { debugInfo.append( "(BLOCKEVENTS processing) " ); - SellAllUtil sellAllUtil = SellAllUtil.get(); - boolean isSellallEnabled = sellAllUtil != null && - SpigotPrison.getInstance().isSellAllEnabled(); - - // This will return true (allow autosell) unless players can toggle autosell and they turned it off: - // This is to be used with other auto sell setting, but never on it's own: - boolean isPlayerAutosellEnabled = - isSellallEnabled && - (!sellAllUtil.isAutoSellPerUserToggleable || - sellAllUtil.isSellallPlayerUserToggleEnabled( - pmEvent.getPlayer() )); - - - - // AutoSell on full inventory when using BLOCKEVENTS: - if ( isBoolean( AutoFeatures.isAutoSellIfInventoryIsFullForBLOCKEVENTSPriority ) && - isPlayerAutosellEnabled && - pmEvent.getSpigotPlayer().isInventoryFull() ) { + if ( SpigotPrison.getInstance().isSellAllEnabled() ) { + + SellAllUtil sellAllUtil = SellAllUtil.get(); - pmEvent.performSellAllOnPlayerInventoryLogged("BLOCKEVENTS priority sellall"); + // This will return true (allow autosell) unless players can toggle autosell and they turned it off: + // This is to be used with other auto sell setting, but never on it's own: + boolean isPlayerAutosellEnabled = + (!sellAllUtil.isAutoSellPerUserToggleable || + sellAllUtil.isSellallPlayerUserToggleEnabled( + pmEvent.getPlayer() )); + + + // AutoSell on full inventory when using BLOCKEVENTS: + if ( isBoolean( AutoFeatures.isAutoSellIfInventoryIsFullForBLOCKEVENTSPriority ) && + isPlayerAutosellEnabled && + pmEvent.getSpigotPlayer().isInventoryFull() ) { + + pmEvent.performSellAllOnPlayerInventoryLogged("BLOCKEVENTS priority sellall"); + // final long nanoStart = System.nanoTime(); // boolean success = SellAllUtil.get().sellAllSell( pmEvent.getPlayer(), // false, false, false, true, true, false); @@ -948,6 +947,7 @@ else if ( results && pmEvent.getBbPriority().isMonitor() && mine != null ) { // // PlayerAutoRankupTask.autoSubmitPlayerRankupTask( pmEvent.getSpigotPlayer(), debugInfo ); // + } } } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/commands/PrisonSpigotGUISellAllCommands.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/commands/PrisonSpigotGUISellAllCommands.java index 8f5274c32..e9bfee34c 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/commands/PrisonSpigotGUISellAllCommands.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/commands/PrisonSpigotGUISellAllCommands.java @@ -7,6 +7,7 @@ import tech.mcprison.prison.internal.CommandSender; import tech.mcprison.prison.output.Output; import tech.mcprison.prison.sellall.messages.SpigotVariousGuiMessages; +import tech.mcprison.prison.spigot.SpigotPrison; import tech.mcprison.prison.spigot.configs.MessagesConfig; import tech.mcprison.prison.spigot.gui.sellall.SellAllAdminBlocksGUI; import tech.mcprison.prison.spigot.sellall.SellAllUtil; @@ -34,10 +35,10 @@ private void sellAllGuiCommand(CommandSender sender, return; } - SellAllUtil sellAllUtil = SellAllUtil.get(); - if (sellAllUtil == null){ + if ( !SpigotPrison.getInstance().isSellAllEnabled() ){ return; } + SellAllUtil sellAllUtil = SellAllUtil.get(); if (!sellAllUtil.openSellAllGUI( p, page, "sellall gui", "close" )){ // If the sender's an admin (OP or have the prison.admin permission) it'll send an error message. diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/commands/PrisonSpigotSellAllCommands.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/commands/PrisonSpigotSellAllCommands.java index 9856f1601..cb5c734cc 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/commands/PrisonSpigotSellAllCommands.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/commands/PrisonSpigotSellAllCommands.java @@ -76,10 +76,10 @@ private void sellAllCurrency(CommandSender sender, return; } - SellAllUtil sellAllUtil = SellAllUtil.get(); - if (sellAllUtil == null){ + if ( !SpigotPrison.getInstance().isSellAllEnabled() ){ return; } + SellAllUtil sellAllUtil = SellAllUtil.get(); if (sellAllUtil.setCurrency(currency)){ Output.get().sendInfo(sender, messages.getString(MessagesConfig.StringID.spigot_message_sellall_currency_edit_success) + " [" + currency + "]"); @@ -115,18 +115,17 @@ private void sellAllDelay(CommandSender sender, description = "True to enable or false to disable.", def = "false") String enable){ - if (!isEnabled()) return; + if (!isEnabled() || !SpigotPrison.getInstance().isSellAllEnabled() ){ + return; + } + SellAllUtil sellAllUtil = SellAllUtil.get(); if (!(enable.equalsIgnoreCase("true") || enable.equalsIgnoreCase("false"))){ Output.get().sendInfo(sender, messages.getString(MessagesConfig.StringID.spigot_message_sellall_boolean_input_invalid)); return; } - SellAllUtil sellAllUtil = SellAllUtil.get(); - if (sellAllUtil == null){ - return; - } boolean enableBoolean = getBoolean(enable); if (sellAllUtil.isSellAllDelayEnabled == enableBoolean){ @@ -154,12 +153,10 @@ private void sellAllDelaySet(CommandSender sender, @Arg(name = "delay", description = "Set delay value in seconds. Defaults to a value of 15 seconds.", def = "15") String delay){ - if (!isEnabled()) return; - - SellAllUtil sellAllUtil = SellAllUtil.get(); - if (sellAllUtil == null){ + if ( !isEnabled() || !SpigotPrison.getInstance().isSellAllEnabled() ){ return; } + SellAllUtil sellAllUtil = SellAllUtil.get(); int delayValue; try { @@ -185,12 +182,10 @@ private void sellAllAutoSell(CommandSender sender, + "[true false perUserToggleable]", def = "true") String enable){ - if (!isEnabled()) return; - - SellAllUtil sellAllUtil = SellAllUtil.get(); - if (sellAllUtil == null){ + if ( !isEnabled() || !SpigotPrison.getInstance().isSellAllEnabled() ){ return; } + SellAllUtil sellAllUtil = SellAllUtil.get(); if (enable.equalsIgnoreCase("perusertoggleable")){ sellAllAutoSellPerUserToggleable(sender, enable); @@ -234,12 +229,10 @@ private void sellAllAutoSellPerUserToggleable(CommandSender sender, description = "'True' to enable or 'false' to disable. [true false]", def = "") String enable){ - if (!isEnabled()) return; - - SellAllUtil sellAllUtil = SellAllUtil.get(); - if (sellAllUtil == null){ + if (!isEnabled() || !SpigotPrison.getInstance().isSellAllEnabled() ){ return; } + SellAllUtil sellAllUtil = SellAllUtil.get(); if ( !enable.equalsIgnoreCase("true") && !enable.equalsIgnoreCase("false") ) { Output.get().sendWarn(sender, messages.getString(MessagesConfig.StringID.spigot_message_sellall_boolean_input_invalid)); @@ -317,10 +310,10 @@ else if (p == null){ } - SellAllUtil sellAllUtil = SellAllUtil.get(); - if (sellAllUtil == null){ + if ( !SpigotPrison.getInstance().isSellAllEnabled() ){ return; } + SellAllUtil sellAllUtil = SellAllUtil.get(); // if (sellAllUtil.isPlayerInDisabledWorld(p)) return; @@ -345,13 +338,10 @@ else if (p == null){ onlyPlayers = true) public void sellAllSellHandCommand(CommandSender sender){ - if (!isEnabled()) return; - - SellAllUtil sellAllUtil = SellAllUtil.get(); - - if (sellAllUtil == null){ + if (!isEnabled() || !SpigotPrison.getInstance().isSellAllEnabled() ){ return; } + SellAllUtil sellAllUtil = SellAllUtil.get(); if (!sellAllUtil.isSellAllHandEnabled){ Output.get().sendWarn(sender, "The command /sellall hand is disabled from the config!"); @@ -387,17 +377,16 @@ public void sellAllSellHandCommand(CommandSender sender){ } public void sellAllSell(Player p){ - if (!isEnabled()) return; + if ( !isEnabled() || !SpigotPrison.getInstance().isSellAllEnabled() ){ + return; + } + SellAllUtil sellAllUtil = SellAllUtil.get(); if (p == null){ Output.get().sendInfo(new SpigotPlayer(p), "&cSorry but you can't use that from the console!"); return; } - SellAllUtil sellAllUtil = SellAllUtil.get(); - if (sellAllUtil == null){ - return; - } // if (sellAllUtil.isPlayerInDisabledWorld(p)) return; @@ -427,7 +416,10 @@ public void sellAllValueOfCommand(CommandSender sender, "Only console or prison commands can include this parameter") String playerName ){ - if (!isEnabled()) return; + if (!isEnabled() || !SpigotPrison.getInstance().isSellAllEnabled() ){ + return; + } + SellAllUtil sellAllUtil = SellAllUtil.get(); Player p = getSpigotPlayer(sender); @@ -471,11 +463,6 @@ else if (p == null){ } - SellAllUtil sellAllUtil = SellAllUtil.get(); - if (sellAllUtil == null){ - return; - } - // if (sellAllUtil.isPlayerInDisabledWorld(p)) return; if (sellAllUtil.isSellAllSellPermissionEnabled){ @@ -501,13 +488,10 @@ else if (p == null){ onlyPlayers = true) public void sellAllValueOfHandCommand(CommandSender sender){ - if (!isEnabled()) return; - - SellAllUtil sellAllUtil = SellAllUtil.get(); - - if (sellAllUtil == null){ + if (!isEnabled() || !SpigotPrison.getInstance().isSellAllEnabled() ){ return; } + SellAllUtil sellAllUtil = SellAllUtil.get(); if (!sellAllUtil.isSellAllHandEnabled){ Output.get().sendWarn(sender, "The command `/sellall valueOfHand` is disabled from the config! (SellAllHandEnabled)"); @@ -548,7 +532,10 @@ public void sellAllValueOfHandCommand(CommandSender sender){ onlyPlayers = true) public void sellAllSellWithDelayCommand(CommandSender sender){ - if (!isEnabled()) return; + if ( !isEnabled() || !SpigotPrison.getInstance().isSellAllEnabled() ){ + return; + } + SellAllUtil sellAllUtil = SellAllUtil.get(); Player p = getSpigotPlayer(sender); @@ -557,10 +544,6 @@ public void sellAllSellWithDelayCommand(CommandSender sender){ return; } - SellAllUtil sellAllUtil = SellAllUtil.get(); - if (sellAllUtil == null){ - return; - } // if (sellAllUtil.isPlayerInDisabledWorld(p)) return; @@ -593,7 +576,10 @@ public void sellAllSellWithDelayCommand(CommandSender sender){ altPermissions = "prison.sellall.toggle", onlyPlayers = true) private void sellAllAutoEnableUser(CommandSender sender){ - if (!isEnabled()) return; + if (!isEnabled() || !SpigotPrison.getInstance().isSellAllEnabled() ){ + return; + } + SellAllUtil sellAllUtil = SellAllUtil.get(); Player p = getSpigotPlayer(sender); @@ -603,10 +589,6 @@ private void sellAllAutoEnableUser(CommandSender sender){ return; } - SellAllUtil sellAllUtil = SellAllUtil.get(); - if (sellAllUtil == null){ - return; - } // if (sellAllUtil.isPlayerInDisabledWorld(p)) return; @@ -700,7 +682,10 @@ private void sellAllAddCommand(CommandSender sender, description = "The Item_ID or block to add to the sellAll Shop.") String itemID, @Arg(name = "Value", description = "The value of the item.") Double value){ - if (!isEnabled()) return; + if (!isEnabled() || !SpigotPrison.getInstance().isSellAllEnabled() ){ + return; + } + SellAllUtil sellAllUtil = SellAllUtil.get(); if (itemID == null){ Output.get().sendWarn(sender, messages.getString(MessagesConfig.StringID.spigot_message_sellall_item_missing_name)); @@ -713,10 +698,6 @@ private void sellAllAddCommand(CommandSender sender, return; } - SellAllUtil sellAllUtil = SellAllUtil.get(); - if (sellAllUtil == null){ - return; - } if (sellAllUtil.sellAllConfig.getConfigurationSection("Items." + itemID) != null){ Output.get().sendWarn(sender, itemID + " " + messages.getString(MessagesConfig.StringID.spigot_message_sellall_item_already_added)); @@ -753,10 +734,10 @@ public void sellAllAddCommand(XMaterial blockAdd, Double value){ String itemID = blockAdd.name(); - SellAllUtil sellAllUtil = SellAllUtil.get(); - if (sellAllUtil == null){ + if ( !SpigotPrison.getInstance().isSellAllEnabled() ){ return; } + SellAllUtil sellAllUtil = SellAllUtil.get(); // If the block or item was already configured, then skip this: if (sellAllUtil.sellAllConfig.getConfigurationSection("Items." + itemID) != null){ @@ -775,7 +756,10 @@ public void sellAllAddCommand(XMaterial blockAdd, Double value){ private void sellAllDeleteCommand(CommandSender sender, @Arg(name = "Item_ID", description = "The Item_ID you want to remove.") String itemID){ - if (!isEnabled()) return; + if ( !isEnabled() || !SpigotPrison.getInstance().isSellAllEnabled() ){ + return; + } + SellAllUtil sellAllUtil = SellAllUtil.get(); if (itemID == null){ Output.get().sendWarn(sender, messages.getString(MessagesConfig.StringID.spigot_message_sellall_item_missing_name)); @@ -783,10 +767,6 @@ private void sellAllDeleteCommand(CommandSender sender, } itemID = itemID.toUpperCase(); - SellAllUtil sellAllUtil = SellAllUtil.get(); - if (sellAllUtil == null){ - return; - } if (sellAllUtil.sellAllConfig.getConfigurationSection("Items." + itemID) == null){ Output.get().sendWarn(sender, itemID + " " + messages.getString(MessagesConfig.StringID.spigot_message_sellall_cant_find_item_config)); @@ -807,7 +787,10 @@ private void sellAllEditCommand(CommandSender sender, @Arg(name = "Item_ID", description = "The Item_ID or block to add to the sellAll Shop.") String itemID, @Arg(name = "Value", description = "The value of the item.") Double value){ - if (!isEnabled()) return; + if ( !isEnabled() || !SpigotPrison.getInstance().isSellAllEnabled() ){ + return; + } + SellAllUtil sellAllUtil = SellAllUtil.get(); if (itemID == null){ Output.get().sendWarn(sender, messages.getString(MessagesConfig.StringID.spigot_message_sellall_item_missing_name)); @@ -820,10 +803,6 @@ private void sellAllEditCommand(CommandSender sender, return; } - SellAllUtil sellAllUtil = SellAllUtil.get(); - if (sellAllUtil == null){ - return; - } if (sellAllUtil.sellAllConfig.getConfigurationSection("Items." + itemID) == null){ Output.get().sendWarn(sender, itemID + " " + messages.getString(MessagesConfig.StringID.spigot_message_sellall_item_not_found)); @@ -860,12 +839,10 @@ private void sellAllMultiplierCommand(CommandSender sender, + "columns in the output by using 'cols=16', where the default is 10 columns. ") String options ) { - if (!isEnabled()) return; - - SellAllUtil sellAllUtil = SellAllUtil.get(); - if (sellAllUtil == null){ + if ( !isEnabled() || !SpigotPrison.getInstance().isSellAllEnabled() ){ return; } + SellAllUtil sellAllUtil = SellAllUtil.get(); if (!sellAllUtil.isSellAllMultiplierEnabled){ Output.get().sendWarn(sender, messages.getString(MessagesConfig.StringID.spigot_message_sellall_multiplier_are_disabled)); @@ -1070,12 +1047,10 @@ private void sellAllAddMultiplierCommand(CommandSender sender, @Arg(name = "rank", description = "The rank name for the multiplier.") String rank, @Arg(name = "multiplier", description = "Multiplier value.") Double multiplier) { - if (!isEnabled()) return; - - SellAllUtil sellAllUtil = SellAllUtil.get(); - if (sellAllUtil == null){ + if (!isEnabled() || !SpigotPrison.getInstance().isSellAllEnabled() ){ return; } + SellAllUtil sellAllUtil = SellAllUtil.get(); if (!sellAllUtil.isSellAllMultiplierEnabled){ Output.get().sendWarn(sender, messages.getString(MessagesConfig.StringID.spigot_message_sellall_multiplier_are_disabled)); @@ -1096,12 +1071,10 @@ private void sellAllAddMultiplierCommand(CommandSender sender, private void sellAllDeleteMultiplierCommand(CommandSender sender, @Arg(name = "Rank", description = "The rank name of the multiplier.") String rank){ - if (!isEnabled()) return; - - SellAllUtil sellAllUtil = SellAllUtil.get(); - if (sellAllUtil == null){ + if ( !isEnabled() || !SpigotPrison.getInstance().isSellAllEnabled() ){ return; } + SellAllUtil sellAllUtil = SellAllUtil.get(); if (!sellAllUtil.isSellAllMultiplierEnabled){ Output.get().sendWarn(sender, messages.getString(MessagesConfig.StringID.spigot_message_sellall_multiplier_are_disabled)); @@ -1136,12 +1109,10 @@ private void sellAllMultiplierDeleteLadderCommand( ) { - if (!isEnabled()) return; - - SellAllUtil sellAllUtil = SellAllUtil.get(); - if (sellAllUtil == null){ + if ( !isEnabled() || !SpigotPrison.getInstance().isSellAllEnabled() ){ return; } + SellAllUtil sellAllUtil = SellAllUtil.get(); if (!sellAllUtil.isSellAllMultiplierEnabled){ Output.get().sendWarn(sender, messages.getString(MessagesConfig.StringID.spigot_message_sellall_multiplier_are_disabled)); @@ -1210,12 +1181,10 @@ private void sellAllMultiplierAddLadderCommand( ) { - if (!isEnabled()) return; - - SellAllUtil sellAllUtil = SellAllUtil.get(); - if (sellAllUtil == null){ + if ( !isEnabled() || !SpigotPrison.getInstance().isSellAllEnabled() ){ return; } + SellAllUtil sellAllUtil = SellAllUtil.get(); if (!sellAllUtil.isSellAllMultiplierEnabled){ Output.get().sendWarn(sender, messages.getString(MessagesConfig.StringID.spigot_message_sellall_multiplier_are_disabled)); @@ -1280,7 +1249,10 @@ private void sellAllMultiplierAddLadderCommand( private void sellAllToolsTriggerToggle(CommandSender sender, @Arg(name = "Boolean", description = "Enable or disable", def = "true") String enable){ - if (!isEnabled()) return; + if (!isEnabled() || !SpigotPrison.getInstance().isSellAllEnabled() ){ + return; + } + SellAllUtil sellAllUtil = SellAllUtil.get(); if (enable.equalsIgnoreCase("null")){ sender.dispatchCommand("sellall toolsTrigger help"); @@ -1294,10 +1266,6 @@ private void sellAllToolsTriggerToggle(CommandSender sender, return; } - SellAllUtil sellAllUtil = SellAllUtil.get(); - if (sellAllUtil == null){ - return; - } boolean enableInput = getBoolean(enable); if (sellAllUtil.isSellAllItemTriggerEnabled == enableInput) { @@ -1324,12 +1292,10 @@ private void sellAllToolsTriggerToggle(CommandSender sender, private void sellAllTriggerAdd(CommandSender sender, @Arg(name = "Item", description = "Item name") String itemID){ - if (!isEnabled()) return; - - SellAllUtil sellAllUtil = SellAllUtil.get(); - if (sellAllUtil == null){ + if (!isEnabled() || !SpigotPrison.getInstance().isSellAllEnabled() ){ return; } + SellAllUtil sellAllUtil = SellAllUtil.get(); if (!sellAllUtil.isSellAllItemTriggerEnabled){ Output.get().sendWarn(sender, messages.getString(MessagesConfig.StringID.spigot_message_sellall_trigger_is_disabled)); @@ -1365,12 +1331,10 @@ private void sellAllTriggerAdd(CommandSender sender, private void sellAllTriggerDelete(CommandSender sender, @Arg(name = "Item", description = "Item name") String itemID){ - if (!isEnabled()) return; - - SellAllUtil sellAllUtil = SellAllUtil.get(); - if (sellAllUtil == null){ + if (!isEnabled() || !SpigotPrison.getInstance().isSellAllEnabled() ){ return; } + SellAllUtil sellAllUtil = SellAllUtil.get(); if (!sellAllUtil.isSellAllItemTriggerEnabled){ Output.get().sendWarn(sender, messages.getString(MessagesConfig.StringID.spigot_message_sellall_trigger_is_disabled)); @@ -1423,12 +1387,10 @@ private void sellAllSetDefaultCommand(CommandSender sender){ permissions = "prison.admin", onlyPlayers = false) private void sellAllListItems( CommandSender sender ) { - if (!isEnabled()) return; - - SellAllUtil sellAllUtil = SellAllUtil.get(); - if (sellAllUtil == null){ + if ( !isEnabled() || !SpigotPrison.getInstance().isSellAllEnabled() ){ return; } + SellAllUtil sellAllUtil = SellAllUtil.get(); TreeMap items = new TreeMap<>( sellAllUtil.getSellAllItems() ); DecimalFormat fFmt = Prison.get().getDecimalFormat("#,##0.00"); diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotPlayer.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotPlayer.java index d09d7a6d9..453d6bcc6 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotPlayer.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotPlayer.java @@ -860,30 +860,29 @@ public boolean isAutoSellEnabled() { return isAutoSellEnabled( null ); } public boolean isAutoSellEnabled( StringBuilder debugInfo ) { + boolean results = false; - boolean isSellallEnabled = SellAllUtil.get() != null && - SpigotPrison.getInstance().isSellAllEnabled(); - - boolean isAutoSellPerUserToggleable = SellAllUtil.get().isAutoSellPerUserToggleable; - - boolean isPlayerAutoSellTurnedOff = isAutoSellPerUserToggleable && - !SellAllUtil.get().isSellallPlayerUserToggleEnabled( + if ( SpigotPrison.getInstance().isSellAllEnabled() ) { + + boolean isAutoSellPerUserToggleable = SellAllUtil.get().isAutoSellPerUserToggleable; + + boolean isPlayerAutoSellTurnedOff = isAutoSellPerUserToggleable && + !SellAllUtil.get().isSellallPlayerUserToggleEnabled( getWrapper() ); - - if ( debugInfo != null && isPlayerAutoSellTurnedOff ) { - debugInfo.append( Output.get().getColorCodeWarning() ); - debugInfo.append( "(Player toggled off autosell) " ); - debugInfo.append( Output.get().getColorCodeDebug() ); + + if ( debugInfo != null && isPlayerAutoSellTurnedOff ) { + debugInfo.append( Output.get().getColorCodeWarning() ); + debugInfo.append( "(Player toggled off autosell) " ); + debugInfo.append( Output.get().getColorCodeDebug() ); + } + + // This will return true (allow autosell) unless players can toggle autosell and they turned it off: + // This is to be used with other auto sell setting, but never on it's own: + results = !isAutoSellPerUserToggleable || + isPlayerAutoSellTurnedOff; } - // This will return true (allow autosell) unless players can toggle autosell and they turned it off: - // This is to be used with other auto sell setting, but never on it's own: - boolean isPlayerAutosellEnabled = - isSellallEnabled && - ( !isAutoSellPerUserToggleable || - isPlayerAutoSellTurnedOff ); - - return isPlayerAutosellEnabled; + return results; } @@ -922,8 +921,7 @@ public boolean isAutoSellByPermEnabled( boolean isPlayerAutosellEnabled ) { AutoFeaturesWrapper afw = AutoFeaturesWrapper.getInstance(); - boolean isSellallEnabled = SellAllUtil.get() != null && - SpigotPrison.getInstance().isSellAllEnabled(); + boolean isSellallEnabled = SpigotPrison.getInstance().isSellAllEnabled(); if ( isSellallEnabled && isPlayerAutosellEnabled && !isOp() ) { From 2f7dee897275ad857e9b1a846791bc1ee949663c Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 18 Nov 2023 12:22:52 -0500 Subject: [PATCH 148/151] Modules: Changed the way some of the module management is used to help prevent errors when a module is disabled. Suppress disabled modules from the placeholder list... only Ranks and Mines, which covers all of the placeholders. --- docs/changelog_v3.3.x.md | 8 ++++- .../prison/modules/ModuleManager.java | 11 +++++++ .../placeholders/PlaceholderManager.java | 33 ++++++++++++++++++- .../mcprison/prison/mines/PrisonMines.java | 5 ++- .../mcprison/prison/ranks/PrisonRanks.java | 4 ++- .../autofeatures/AutoManagerFeatures.java | 4 --- 6 files changed, 57 insertions(+), 8 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 486ffe94e..96bfe287d 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -14,7 +14,12 @@ These change logs represent the work that has been going on within prison. -# 3.3.0-alpha.15h 2023-11-16 +# 3.3.0-alpha.15h 2023-11-18 + + +* **Modules: Changed the way some of the module management is used to help prevent errors when a module is disabled.** +Suppress disabled modules from the placeholder list... only Ranks and Mines, which covers all of the placeholders. + * **Sellall: Standardize how sellall is being checked to see if it's enabled.** @@ -24,6 +29,7 @@ There was a problem with the older way things were being handled that was causin * **Economy support for CoinsEngine: support has been initially added**, but it is unsure if it is working correctly. This request originated from pingu and they said it's not working, but has not provided any more information. Unsure how it's not working, or if they cannot use it the way they originally envisioned because sellall cannot support different currencies for different items within sellall. Because of the lack of an API jar to be used, a new sub-project 'prison-misc' was created to be able to generate a pseudo-shell api for the CoinsEngine plugin. This pseduo api jar is used strictly to allow the successful compiling of the prison's economy hooks for CoinsEngine. +NOTE: I have not heard back from pingu to know if this is working. If you try to use this plugin and you have issues, please contact me on our discord support server. * **Block Converters: Change the usage to Player instead of RankPlayer since if ranks are disabled then RankPlayer could not exist.** diff --git a/prison-core/src/main/java/tech/mcprison/prison/modules/ModuleManager.java b/prison-core/src/main/java/tech/mcprison/prison/modules/ModuleManager.java index 73b8c6d15..532424f75 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/modules/ModuleManager.java +++ b/prison-core/src/main/java/tech/mcprison/prison/modules/ModuleManager.java @@ -37,6 +37,9 @@ public class ModuleManager { public static final String MODULE_MANAGER_DIRECTORY = "module_conf"; + public static final String MODULE_NAME_MINES = "Mines"; + public static final String MODULE_NAME_RANKS = "Ranks"; + private List modules; private List disabledModules; private File moduleRoot; @@ -48,6 +51,14 @@ public ModuleManager() { moduleRoot = getModuleRootDefault(); } + + public boolean isEnabled( String moduleName ) { + + Module module = getModule( moduleName ); + + return module != null && module.isEnabled(); + } + public static File getModuleRootDefault() { File moduleRoot = new File(PrisonAPI.getPluginDirectory(), MODULE_MANAGER_DIRECTORY); if (!moduleRoot.exists()) { diff --git a/prison-core/src/main/java/tech/mcprison/prison/placeholders/PlaceholderManager.java b/prison-core/src/main/java/tech/mcprison/prison/placeholders/PlaceholderManager.java index 3a15958e2..b3cf4bfe7 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/placeholders/PlaceholderManager.java +++ b/prison-core/src/main/java/tech/mcprison/prison/placeholders/PlaceholderManager.java @@ -4,6 +4,9 @@ import java.util.List; import java.util.regex.Pattern; +import tech.mcprison.prison.Prison; +import tech.mcprison.prison.modules.ModuleManager; + public class PlaceholderManager { public static final String PRISON_PLACEHOLDER_PREFIX = "prison"; @@ -799,11 +802,34 @@ public static List getAllChatList( boolean omitSuppressable) { boolean hasDeprecated = false; + + boolean isMinesEnabled = Prison.get().getModuleManager().isEnabled( ModuleManager.MODULE_NAME_MINES ); + boolean isRanksEnabled = Prison.get().getModuleManager().isEnabled( ModuleManager.MODULE_NAME_RANKS ); + + int totalCount = 0; for ( PlaceholderFlags type : PlaceholderFlags.values() ) { if ( type == PlaceholderFlags.ALIAS || type == PlaceholderFlags.SUPRESS ) { - break; + continue; + } + + if ( !isMinesEnabled && ( + type == PlaceholderFlags.MINES || + type == PlaceholderFlags.MINEPLAYERS || + type == PlaceholderFlags.PLAYERBLOCKS || + type == PlaceholderFlags.STATSMINES )) { + continue; + } + + if ( !isRanksEnabled && ( +// type == PlaceholderFlags.PLAYER && placeholder.name().toLowerCase().contains("rank") || + type == PlaceholderFlags.LADDERS || + type == PlaceholderFlags.RANKS || + type == PlaceholderFlags.RANKPLAYERS || + type == PlaceholderFlags.STATSPLAYERS || + type == PlaceholderFlags.STATSRANKS )) { + continue; } int pos = results.size(); @@ -842,6 +868,11 @@ else if ( type == PlaceholderFlags.STATSRANKS ) { int count = 0; for ( PrisonPlaceHolders ph : values() ) { + if ( !isRanksEnabled && ( + type == PlaceholderFlags.PLAYER && ph.name().toLowerCase().contains("rank") )) { + break; + } + if ( ph.getFlags().contains( type ) && ( !omitSuppressable || omitSuppressable && !ph.isSuppressed() && !ph.isAlias() )) { diff --git a/prison-mines/src/main/java/tech/mcprison/prison/mines/PrisonMines.java b/prison-mines/src/main/java/tech/mcprison/prison/mines/PrisonMines.java index da33a9961..d827c336d 100644 --- a/prison-mines/src/main/java/tech/mcprison/prison/mines/PrisonMines.java +++ b/prison-mines/src/main/java/tech/mcprison/prison/mines/PrisonMines.java @@ -38,6 +38,7 @@ import tech.mcprison.prison.mines.managers.MineManager; import tech.mcprison.prison.mines.managers.MineManager.MineSortOrder; import tech.mcprison.prison.modules.Module; +import tech.mcprison.prison.modules.ModuleManager; import tech.mcprison.prison.output.Output; import tech.mcprison.prison.store.Database; import tech.mcprison.prison.util.Location; @@ -49,7 +50,9 @@ * @author The MC-Prison Team */ public class PrisonMines extends Module { - public static final String MODULE_NAME = "Mines"; + + public static final String MODULE_NAME = ModuleManager.MODULE_NAME_MINES; +// public static final String MODULE_NAME = "Mines"; private static PrisonMines i = null; private MinesConfig config; diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/PrisonRanks.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/PrisonRanks.java index c42474100..80527e11c 100644 --- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/PrisonRanks.java +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/PrisonRanks.java @@ -28,6 +28,7 @@ import tech.mcprison.prison.integration.IntegrationType; import tech.mcprison.prison.internal.Player; import tech.mcprison.prison.localization.LocaleManager; +import tech.mcprison.prison.modules.ModuleManager; import tech.mcprison.prison.modules.ModuleStatus; import tech.mcprison.prison.output.LogLevel; import tech.mcprison.prison.output.Output; @@ -55,7 +56,8 @@ public class PrisonRanks extends PrisonRanksMessages { - public static final String MODULE_NAME = "Ranks"; + public static final String MODULE_NAME = ModuleManager.MODULE_NAME_RANKS; +// public static final String MODULE_NAME = "Ranks"; /* * Fields & Constants */ diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerFeatures.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerFeatures.java index 56a89af86..79da13c74 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerFeatures.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerFeatures.java @@ -3273,10 +3273,6 @@ public boolean checkBlockConverterEventTrigger(PrisonMinesBlockBreakEvent pmEven long start = System.currentTimeMillis(); - if ( PrisonRanks.getInstance().isEnabled() ) { - - } - SpigotPlayer sPlayer = pmEvent.getSpigotPlayer(); // RankPlayer rPlayer = PrisonRanks.getInstance().getPlayerManager().getPlayer( pmEvent.getSpigotPlayer() ); String blockName = pmEvent.getSpigotBlock().getBlockName(); From 363ab7dc48e701f316e7b8b3820c6123d45bf52b Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 18 Nov 2023 12:24:51 -0500 Subject: [PATCH 149/151] Fixed an issue with ranks being disabled. It now skips over this processing when ranks are disabled. --- docs/changelog_v3.3.x.md | 4 ++ .../prison/spigot/SpigotPlatform.java | 51 +++++++++++-------- 2 files changed, 33 insertions(+), 22 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 96bfe287d..3a0876ba4 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -17,6 +17,10 @@ These change logs represent the work that has been going on within prison. # 3.3.0-alpha.15h 2023-11-18 +* **Fixed an issue with ranks being disabled. It now skips over this processing when ranks are disabled.** + + + * **Modules: Changed the way some of the module management is used to help prevent errors when a module is disabled.** Suppress disabled modules from the placeholder list... only Ranks and Mines, which covers all of the placeholders. diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/SpigotPlatform.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/SpigotPlatform.java index a263f8f33..3bfc67237 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/SpigotPlatform.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/SpigotPlatform.java @@ -3049,31 +3049,38 @@ public String getMinesListString() { public String getRanksListString() { StringBuilder sb = new StringBuilder(); - LadderCommands lc = + if ( PrisonRanks.getInstance() != null && PrisonRanks.getInstance().isEnabled() ) { + + LadderCommands lc = PrisonRanks.getInstance().getRankManager().getLadderCommands(); - - RanksCommands rc = + + RanksCommands rc = PrisonRanks.getInstance().getRankManager().getRanksCommands(); - - sb.append( "\n\n" ); - - ChatDisplay displayLadders = lc.getLadderList(); - - sb.append( displayLadders.toStringBuilder() ); - sb.append( "\n" ); - - - RankPlayer rPlayer = null; - - ChatDisplay displayRanks = new ChatDisplay("Ranks"); - rc.listAllRanksByLadders( displayRanks, true, rPlayer ); - - sb.append( displayRanks.toStringBuilder() ); - sb.append( "\n" ); - - - rc.listAllRanksByInfo( sb ); + + sb.append( "\n\n" ); + + ChatDisplay displayLadders = lc.getLadderList(); + + sb.append( displayLadders.toStringBuilder() ); + sb.append( "\n" ); + + + RankPlayer rPlayer = null; + + ChatDisplay displayRanks = new ChatDisplay("Ranks"); + rc.listAllRanksByLadders( displayRanks, true, rPlayer ); + + sb.append( displayRanks.toStringBuilder() ); + sb.append( "\n" ); + + + rc.listAllRanksByInfo( sb ); // rc.allRanksInfoDetails( sb ); + } + else { + sb.append( "Ranks are disabled.\n\n" ); + } + return sb.toString(); // return Text.stripColor( sb.toString() ); From a0c6803c9be9a23b04a7d557cc9bfceb6eda0e9e Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 18 Nov 2023 13:15:03 -0500 Subject: [PATCH 150/151] Release v3.3.0-alpha.16 2023-11-18 --- docs/changelog_v3.3.x.md | 5 ++++- gradle.properties | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 3a0876ba4..13736b8f1 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -14,7 +14,10 @@ These change logs represent the work that has been going on within prison. -# 3.3.0-alpha.15h 2023-11-18 +# 3.3.0-alpha.16 2023-11-18 + + +# 3.3.0-alpha.16 2023-11-18 * **Fixed an issue with ranks being disabled. It now skips over this processing when ranks are disabled.** diff --git a/gradle.properties b/gradle.properties index aa000e5f9..01d7ea2a1 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,7 +3,7 @@ ## # This is actually the "correct" place to define the version for the project. ## # Used within build.gradle with ${project.version}. ## # Can be overridden on the command line: gradle -Pversion=3.2.1-alpha.3 -version=3.3.0-alpha.15h +version=3.3.0-alpha.16 From b2a37f4554d21e3d98c39cd461243714e466cddc Mon Sep 17 00:00:00 2001 From: rbluer <665978+rbluer@users.noreply.github.com> Date: Sat, 18 Nov 2023 15:20:53 -0500 Subject: [PATCH 151/151] Update change logs for v3.3.0-alpha.16 --- docs/changelog_v3.2.x.md | 2 +- docs/changelog_v3.3.x.md | 355 +------------ docs/knownissues_v3.2.x.md | 2 + docs/knownissues_v3.3.x.md | 2 + docs/prison_changelog_v3.3.0-alpha.14.md | 2 +- docs/prison_changelog_v3.3.0-alpha.15.md | 2 +- docs/prison_changelog_v3.3.0-alpha.16.md | 646 +++++++++++++++++++++++ docs/prison_changelogs.md | 6 +- docs/prison_docs_000_toc.md | 5 +- 9 files changed, 666 insertions(+), 356 deletions(-) create mode 100644 docs/prison_changelog_v3.3.0-alpha.16.md diff --git a/docs/changelog_v3.2.x.md b/docs/changelog_v3.2.x.md index 35bcf3910..6067b2961 100644 --- a/docs/changelog_v3.2.x.md +++ b/docs/changelog_v3.2.x.md @@ -4,7 +4,7 @@ ## Build logs - **[v3.3.x - Current](changelog_v3.3.x.md)** - - [v3.2.0 through v3.3.0-alpha.14](prison_changelogs.md) + - [v3.2.0 through v3.3.0-alpha.16](prison_changelogs.md) - [v3.2.0 - 2019-12-03](prison_changelog_v3.2.0.md)   [v3.2.1 - 2020-09-27](prison_changelog_v3.2.1.md)   [v3.2.2 - 2020-11-21](prison_changelog_v3.2.2.md)   diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index 13736b8f1..0c3a4a436 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -4,7 +4,7 @@ ## Change logs - **[v3.3.0-alpha - Current](changelog_v3.3.x.md)** - - [v3.2.0 through v3.3.0-alpha.14](prison_changelogs.md) + - [v3.2.0 through v3.3.0-alpha.16](prison_changelogs.md) * [Known Issues - Open](knownissues_v3.2.x.md) * [Known Issues - Resolved](knownissues_v3.2.x_resolved.md) @@ -17,7 +17,9 @@ These change logs represent the work that has been going on within prison. # 3.3.0-alpha.16 2023-11-18 -# 3.3.0-alpha.16 2023-11-18 +**v3.3.0-alpha.16 2023-11-18** + +* Update change logs for v3.3.0-alpha.16 * **Fixed an issue with ranks being disabled. It now skips over this processing when ranks are disabled.** @@ -548,361 +550,20 @@ This tries to find the remapped command for all commands by updating the SpigotC * **Fixed an issue where the setting isAutoFeaturesEnabled was not being applied to the permissions which resulted in the perms always being enabled when OPd.** -* **2023-07-07 v3.3.0-alpha.15 Released** - - -* **This doc was failing to generate github docs due to issues with non utf-8 characters.** -Changed them to dashes. Not sure what caused these characters to become non-compliant. - - -* **Update the known issues doc...** - - -* **Doc updates for the latest alpha.15 release.** - - -* **Added comments to the prison-spigot/build.gradle configs to add more descriptive comments.** -Checked the libraries and all are up to date. - - -* **Setup the topN stats to be included in the /prison version information.** - - -* **Added the language files for the three new topN messages.** - - -* **Update the topN command to eliminate the use of the save file.** -All players are dynamically loaded by the refresh task. Stats have been added and are not a new option for the command. -To act as a form of debugging feature, the save of the topN data has been disconnected from the current process. - - -* **Updated ItemsAdder from v3.2.5 to v3.5.0b** -because github's build was failing to find v3.2.5 online and was killing the prison build. - - -* **Update topN Stats.** This is not the same as topNPlayers and this is not yet being used. -This tracks topN on blocks mined, tokens, and the player's ranks and balances. -The comparator was not correct and was fixed. - - -* **MC 1.18 new world height support.** -Prison now supports the newer world heights as found in mc 1.18.x and newer. -The new range for Y is from -64 to 320. - - -* **Bug fix: found that under a rare situation that it was trying to use an empty String with decimal formatting.** -This was found while testing some placeholders while players were offline. - - -* **I made a mistake when adding the new feature to skip player scans on startup.** -I added a new root perm in config.yml that started with `prison-ranks` when `ranks` already existed. Therefore, I changed the defaults in config.sys to fix this and changed the code to allow the old version of the config (the bad version) and the newer version. - - -* **Changes to the help for `/rankup` and `/prestige` commands to make it a little more clearer** as to what is expected with perms and to provide more details. -Added a new config setting to disable the need to use the prestige perm `ranks.rankup.presetiges` which may make it easier to get presetiges working on most servers. -Prestiges still requires the use of the `ranks.user` perm which is the same perm used for `/rankup`. - - -* **Updated the PrisonJarReporter tool to include java versions 19, 20, and 21.** -Also fixed a bug in which if the version signature is not known, then it was returning a null. Now it returns an enum of type "JavaSE_UnknownVersion" which will prevent future errors. - - - -* **2023-06-20: Version 3.3.0-alpha.14c released** - - -* **Totally stupid change: github's compiler forgot how to use overloaded functions so it was trying to use the wrong one.** -Renaming the function should help it's anti-AI skill sets. - - -* **Fixed the way prison was using the nbt-api.** -Now using the correct repo and the newer API functions. - - -* **Trying to get nbt-api setup properly with shadowing.** It looks like it's correctly shadowed, but it's being improperly reported as not being shadowed. I have a conversation with the developer open to figure out what's going on with this issue. - - -* **Update the item-nbt-api library to v2.11.3 from v2.11.2.** -Turned out the maven repo they actually use was not mavencentral.com, of which, has not yet pulled in the updated version. Using the correct repo now. - - -* **Update libraries:** -Update bstats from v3.0.0 to v3.0.2. -Update XSeries from v9.2.0 to v9.4.0. -Update vaultAPI from v1.7.0 to v1.7.1. - - -* **Changed config.yml to be able to bypass the add new player at prison startup.** This would be more related to servers that already have a large player base when they switch to this plugin. -NOTE: It's not possible to fully test all conditions where a player object may be null. Use at your own risk if you do not allow prison to scan for new players at startup. If an error is found, please contact support ASAP in our discord server so we can get it fixed for you. - - -2023-06-13 : -* **Update how the player objects are written when dirty.** There were some situations where the RankPlayer object would be written to the file system 2 or 3 times for one change. -The logic of how things are nested remains the same (to minimize breakage of the code), but the RankPlayer is not utilizing a dirty flag internally so if it's saved once, it skip the other attempts to save without changes. - - -* **Simple example illustrating the weakness of doubles with large values.** - - -* **Update nbt api to v2.11.2 from v2.11.1** - - -* **Added ExaltedEconomy to the soft depends so prison will wait until it is loaded before trying to startup.** 2023-05-24 - - -* **Fixed an issue that if the prison config files are manually modified and as a result, the block events cannot be parsed, this fix prevents a null value being inserted in to the loaded block events.** -For example, a trailing comma would produce a null block event because the parser that prison uses will read the comma, then with nothing else following it, it injects a null in to the collection of raw data for the block events. Then when that raw data is parsed, it passed along that null as a valid block event. The fix, prevents any of the nulls from being added to the active block events. - - -* **A sellall gui message that was supposed to say that the gui was not enabled only said sellall was not enabled. Added a new message to clearly state it's the gui that is not enabled.** - - -* **Get part of sellall to work if ranks are disabled. The command /sellall sell works, but the other sellall commands need to be tested and fixed.** - - -* **Bug fix: bstats and topn was using the wrong function to check to see if ranks were enabled.** - - -* **Fixed an issue when cannot get a player from bukkit** - - -* **AutoFeatures bug fix: If normal drops is enabled (no auto pickup), and sellall was disabled, then normal drops were being disabled.** -The location of checking for if sellall was active was in the wrong location, which was preventing prison from actually dropping the blocks for the player. - - -* **Fixed an issue with prison utils potions where if the player was null, then it was throwing an NPE. ** - - -* **AutoFeatures: Rev Enchants JackHammerEvent: Bug fix: The jackhammer event was not returning a list of all of the blocks involved in the event, which could be excluding hundreds if not more than 1000 blocks.** -The fix, uses the two points to calculate which blocks to include, and then include them through that cuboid instead of getting a list of blocks from the event. - - -* **BugFix: Fixes an issue with sellall where it is trying to sell an invalid ItemStack.** -As a result, the sellall pays the player for the itemstack but the itemstack is not removed. This fixes it by not trying to sell the questionable itemstacks. - - -* **AutoFeatures: Add a bukkit drops multiplier which is applied to the bukkit drops before the fortune calculations are performed.** -This can be used to reduce the total number of drops if a value less than 1.0 is used. A value of 1.0 does nothing. A value greater than one will increase the bukkit drops. All values are floored and are integers. - - -**Update to v3.3.0-alpha.14b** 2023-02-26 - - -* **AutoFeatures bug fix: If global fortune multiplier is set to a value lower than 1, then there is a risk of zero drops; this prevents zero drops and returns a drop of one.** - - -* **Fixed an issue with the initial event check for events that will break multiple blocks.** -The issue is that the initial check will ignore the event if the primary block is air. The issue is that since the events are fired based upon the BlockBreakEvent then the odds of the primary block is AIR is very high. So for those events, the primary block should not be checked for AIR to be bypassed. This fix allows things like explosions to work. - - -**Update to v3.3.0-alpha.14a** 2023-02-25 - - -* **Enhanced the debug reporting for fortune calculations and fixed a few uses of the newer fortune settings, some of which were used in the wrong locations.** - - -* **Updated the formatting on the prison's mine wand for debug reporting of which blocks are clicked on.** -The information has been cleaned up to be easier to read and follow. It's now being logged in the console too so the details can more easily be reported back for troubleshooting. - - -* **Updated the auto features config file to include the ACCESS priorities in the list of priorities so its better understood what the real options are.** - - -* **Enhanced some of the auto features logging related to fortune, silk touch, and event and drop canceling to eliminate ambiguity and provide more specific details.** - - -* **Fixed an issue with player counts being doubled. Counts should no longer be done within the auto pickup or the normal drops... it's being handled at a higher level for consistency with other priorities.** - - -* **Added a fortune multiplier that is applied to all fortune calculations, which allows for increasing or decreasing the results of the fortune.** - - -* **French support added by Maxcension. Thanks Maxcension!** - - -* **Move the check for access to the OnBlockBreakMines.ignoreMinesBlockBreakEvent so it is logged with the other conditions.** - - -* **Setup minecraft statistics so prison can report block mining through a new setting within the auto features.** - -* **Enable silk touch enchantment by dropping the actual blocks that are being broke.** -If alt fortune is being used, then fortune will apply to these silked drops. -If players place silked blocks back in the mines (fi that feature is enabled), prison will ignore those blocks and won't break them... it will let bukkit or another plugin deal with them, but it will not apply any fortune to them. - -* **Bug Fix autosell: was trying to access autosell when it was disabled.** - - -* **Update google gson (json IO tool) from v2.8.6 to v2.10.1** - - -* **Update google guava from v19.0 to v31.1-jre. Guava is used for internal event listeners.** - - -* **Prison Debug Block Inspector: Expand and enhanced the prison tool to provide an inspection of the block break events.** -Added event block details and drops being canceled for each listener. Reformatted to make it easier to read. - - -* **Remove the optional from getModule functions since java 17.0.6 was failing.** -Not sure if it's an actual java issue, or a problem caused by another plugin, or etc... this works well with java 17.0.2. - - -* **Minor improvements to the EventResultsReasons to show a success and more detailed debug logging.** - - -* **Relocate the ACCESS failure which will trigger a TP to an accessible mine...** -this is relocated because it's not an event, but a behavior triggered by an event condition. - - -* **Setup a temp test to test ItemsAdder.** - - -* **AutoFeatures: new feature to process MONITOR and BLOCKEVENTS only if the block is AIR.** -The reason for this is that if we are monitoring a blockbreak event, then we can assume that the block should be AIR. This setting is important for enchantment plugins handling the block break events, since a non-AIR value would indicate that the player was not successful in breaking the block. -Added more detailed debugging logging if the event is fast-failed or under normal conditions. - - -* **Change the block break priority BLOCKEVENTS to MONITOR. Updated the docs too.** - - -* **Add new autoFeature setting to allow non-prison placed blocks to be handled by bukkit: ifBlockIsAlreadyCountedThenCancelEvent: true. (default setting).** -Prison was canceling the event if it found a block placed in the mine that it did not place during a mine reset. This would allow players to place blocks and then remove them if they have the worldguard perms to do block breaks. -These blocks are not tracked in prison and are not handled. Prison just ignores them. - - -* **Fixed the gui config which it needed to load after loading ranks and mines. So it's initialized a second time in the startup process.** - - -* **Gui Player Mine config settings: Added `Options.Mines.MaterialType.NoMineAccess` which defaults to REDSTONE_BLOCK.** -If it does not exist in a player's GuiConfig.yml file, it will now be auto added. -Also if the `Options.Mines.MaterialType` block list of material types to use for each mine does not exist, it will auto add them, using the first block in the mine's block list. - - -* **Some adjustments to AutoFeatures and monitor priority... it was processing block events under some conditions.** - - -* **Mine BlockEvents: Enables the use of pipes in commands and messages now.** +* **2023-07-07 v3.3.0-alpha.15 Released** -* **MineBombs: Added a new field specifically for the item name for the bomb.** -The mine bombs now auto load upon startup and will auto update now if there is a change in mine data versions. +See [Prison Change log v3.2.3-alpha.15](prison_changelog_v3.3.0-alpha.15.md) -* Changed the example world names in the config.yml file where Prison is disabled. Too many people were running in to the problem where they just happened to have those worlds, and that's where they were trying to use prison. So they were thinking Prison was not working instead of Prison being disable in those worlds because that's what was in the configs. **Prison v3.3.0-alpha.14 2023-01-23** -The following are significant changes that are included in the alpha.14 release since the alpha.13 release was posted. - -* Support for RevEnchants - - -* Added more flexibility in supporting Prison Event Listener priorities for block break events so prison is better suited to support more enchantment plugins under more conditions. Added ACCESS, ACCESSBLOCKBREAKS, and ACCESSMONITOR to provide far more flexibility when prison is NOT managing the block breakage. - - -* General improvements in how Auto Features manages the event listeners for all of the block break events. Includes some bug fixes and performance improvements too. - - -* Preparing to support ItemsAdder... will be available in next alpha release.* - - -* Prison Placeholders: Added a few more, fixed a few bugs, and improved documentation so its easier to understand how to use them. Added more features to the command `/prison placeholders stats`. The stats command can actually be used to troubleshoot issues with third-party plugins trying to use prison placeholders. - - -* Top-n reports and placeholders: bug fixes and added a few more features. - - -* Mine commands: refactor and improvements to some of the general mine commands. - - -* Prison Placeholders: general bug fixes and performance improvements with the placeholder cache. - - -* Prison's bstats: Expanded the reports that are being included. - - -* Prison Command Handler: ability to lockout players from commands and tab-completes based upon perms. - - -* Mines GUI Bug fixes: fixed a few issues. - - -* Issue with vault not working with essentials: Not able to access player's balances through vault and provided alternative paths to resolve this issue. - - -* Prison support new feature: tracking command usage along with average run times: `/prison support cmdStats`. - - -* Improved some of the `/prison support submit` features to include more of the newer data that prison is using. - - -* Updates to a number of libraries that prison uses: -placeholderApi: v2.10.9 to v2.11.2 -XSeries: v9.0.0 to v9.2.0 -item-nbt-api: v2.10.0 to v2.11.1 - - -* Removal of support for MVDW placeholders since it's not able to support some of prison's advanced features, plus it's 100% redundant since PlaceholderAPI works in conjunction with it. No loss of service since PAPI is a better solution and works with MVDW. - - -* Added a Prison Backup feature that can make a backup of all the settings within prison's plugin directory (small zip file backups). It is setup to make a backup whenever it detects a change in the prison versions. In the future, it could be automated to make snapshots of all settings and player status so there can be abilities to "rollback" to a prior instance. - - -* Added new translations: Finnish, Chinese, - - -* Enhanced the player GUIs for mines and ranks to use NBT to control the options to simplify how the options work. Eliminated a lot of old code and added more flexibility. - - -* Enable the sellall command to be ran from the console or from a prison command. - - -* Enhanced the debug logging detail related to the auto features. Provides better logging for troubleshooting. - - -* Using a static global setting for decimal formatting to better control how numeric formatting works with various language settings. - - -* Able to now control suffocation in the mines, so you can now allow players to die if they logged out within a mine and they log back buried in rock. - - -* Able to control mine reset teleportation controls. - - -* Added direct support for translating placeholders through the Prison API so its easier to use externally through another plugin. - - -* Now able to set a prestige rank tag to use for players that do not have a prestige rank. This allows for better customization for chat prefixes. - - -* Fixed a bug when trying to move a mine from one world to another world. There was a conflict with an internal value not being cleared/reset. - - -* Fixed a Prison Mine Bomb bug that was making them incompatible with bukkit 1.8.8. - - -* Fixed a bug with how a vector's length was being calculated. Not sure how frequently this would have been used. - - -* Refactoring Prison Backpacks. Getting ready to hook them up to a new internal backpack cache to improve performance. Not yet completed. - - -* Fixed bug with /rankupmax and rewrote prestiges to better align it with the ranks module instead of relying upon the GUI code to manage it. - - -* Enhanced many mine and rank commands to apply changes to all ranks or all mines with one command to make it easier to customize prison. - - -* New feature setting (optional): Forced rankup as soon as the player earns enough money through sellall. - - -* New feature setting (optional): Forced sellall before performing a prestige. - - -* New feature setting (optional): Prevent access to prior mines when ranking up. This foces the player to only have access to mines that are linked to the current rank. This feature allows the use of Mine and TP access by rank instead of having to setup complex settings with perms through a permission plugin. +See [Prison Change log v3.2.3-alpha.14](prison_changelog_v3.3.0-alpha.14.md) @@ -910,8 +571,6 @@ item-nbt-api: v2.10.0 to v2.11.1 - - **3.3.0-alpha.13 2022-08-25** Highlights of some of the changes included in this alpha.13 release. Please see the change logs for all details. diff --git a/docs/knownissues_v3.2.x.md b/docs/knownissues_v3.2.x.md index 2f4d95873..9574ecb67 100644 --- a/docs/knownissues_v3.2.x.md +++ b/docs/knownissues_v3.2.x.md @@ -7,6 +7,8 @@ a short list of To Do's. This list is intended to help work through known issues, and/or to serve as items that should be added, or fixed. +* **[v3.3.0-alpha - Current](changelog_v3.3.x.md)** + * [Known Issues - Resolved](knownissues_v3.2.x_resolved.md) diff --git a/docs/knownissues_v3.3.x.md b/docs/knownissues_v3.3.x.md index b51f664f2..1d6b7bff6 100644 --- a/docs/knownissues_v3.3.x.md +++ b/docs/knownissues_v3.3.x.md @@ -4,6 +4,8 @@ These known issues are an informal list of concerns and bugs. Also includes some wish-list items too. +Not everything is logged here. Please see the changelog for fixes and new features that were actually added. + These are notes for personal references. These are not intended to explain anything useful, but they do track some issues and perspectives that may not be fully expressed in the change logs because initial impressions may not turn out to be the actual problem or the final course of changes and enhancements. diff --git a/docs/prison_changelog_v3.3.0-alpha.14.md b/docs/prison_changelog_v3.3.0-alpha.14.md index e995dab6c..202b8f027 100644 --- a/docs/prison_changelog_v3.3.0-alpha.14.md +++ b/docs/prison_changelog_v3.3.0-alpha.14.md @@ -4,7 +4,7 @@ ## Build logs - **[v3.3.0-alpha - Current](changelog_v3.3.x.md)** - - [v3.2.0 through v3.3.0-alpha.15](prison_changelogs.md) + - [v3.2.0 through v3.3.0-alpha.16](prison_changelogs.md) These build logs represent the work that has been going on within prison. diff --git a/docs/prison_changelog_v3.3.0-alpha.15.md b/docs/prison_changelog_v3.3.0-alpha.15.md index 21d8d1fcb..44cf900a5 100644 --- a/docs/prison_changelog_v3.3.0-alpha.15.md +++ b/docs/prison_changelog_v3.3.0-alpha.15.md @@ -4,7 +4,7 @@ ## Build logs - **[v3.3.0-alpha - Current](changelog_v3.3.x.md)** - - [v3.2.0 through v3.3.0-alpha.15](prison_changelogs.md) + - [v3.2.0 through v3.3.0-alpha.16](prison_changelogs.md) These build logs represent the work that has been going on within prison. diff --git a/docs/prison_changelog_v3.3.0-alpha.16.md b/docs/prison_changelog_v3.3.0-alpha.16.md new file mode 100644 index 000000000..9df2c680e --- /dev/null +++ b/docs/prison_changelog_v3.3.0-alpha.16.md @@ -0,0 +1,646 @@ +[Prison Documents - Table of Contents](prison_docs_000_toc.md) + +## Prison Build Logs for v3.3.x + +## Build logs + - **[v3.3.0-alpha - Current](changelog_v3.3.x.md)** + - [v3.2.0 through v3.3.0-alpha.16](prison_changelogs.md) + + +These build logs represent the work that has been going on within prison. + + +# 3.3.0-alpha.16 2023-11-18 + + + +The following is a highlight of changes for the alpha.16 release since the alpha.15 release. + + +* Bug fix: A library that prison uses broke with the release of Spigot 1.20.2 due to new parameter overloading that spigot introduce, that resulted in ambiguous parameter failures. + + +* Auto Features: Many updates and enhancements. + + +* Sellall: Many updates and enhancements from API to GUI and autofeatures integration. + - Streamlined to work with prison's custom blocks instead of just XMaterial items. + - New functionality to improve managing what's been sold, or just getting their value. Extended a lot of this new functionality to the prison APIs. + - Added many new default items + - Changed all of the commands under sellall to better organize like commands in to sub-commands + - Rank multipliers now works for all ranks, not just prestiges. New commands to reset all multipliers for ladders (which is great if you have a few thousand prestige ranks). + - If blocks could not be sold through auto features autosell, it will generate debug mmessages so it's easier to track why blocks are not being sold. + - Able to disable the "nothing to sell" message so it stops spamming the player. + - For different server configs, where there are issues that prevent autosell from being used, such as other plugins placing blocks in the player's inventory, you can now force a sellall after the block break event is finished being processed. + - Sellall Multipliers - Many new features and commands. Explore with `/sellall multiplier` and use the keyword `help` on each command for more details. The multiplier list can use different column widths to better support thousands of prestige ranks. + + + +* Prison's command handler: Updates and a few enhancements. + - Worlds that are disabled in config.yml prevents prison's command handler from working in those worlds, thus shutting down any and all aspects of prison in those worlds. Use carefully since no warnings will be shown in those worlds that prison is ignoring all commands issued from within those worlds. + + +* Fixed an issue with the player's inventory not matching prison's internal code vs bukkit's. + + +* Expanded Prison's APIs so its easier to use prison's internals within other plugins for the most flexibility in customizing your servers. + + +* Multi-language support files now supports: + - `*none*` keyword to suppress any text. Returns an empty String. + - Now supports line breaks within messages. Use `{br}` which is similar to the html break: `
` but cannot use the `<` or `>`. The `{}` is typical of placeholders. + + +* Improvements to Prison's debug mode and block inspector to make is easier to address issues. + - Debug mode can now be tied to a single person to prevent the console from being spammed + + +* Prison Mine Bombs - Can now identify which mines specific bombs can be use in, or excluded from. Includes a global setting in config.yml so individual bombs do not need to be configured to be excluded from certain mines. + + +* Prison support - New features + - Adding a new HTML bases support file. More work needs to be done with it before making it the primary tool. + - Changed servers for submitting support help files... they are not encrypted and password protected. And they are purged in 7 days. + + +* Mines - + - Mine tracer now has an option to 'clear' the whole mine, mark jjust the 'corners', or the standard full tracer. + - Found and fixed a sync task that was a possible cause of jitters. This helps when the server is under a heavy load. + - Added a `/mtop` command. `/mines top` which teleports a player to the top of the mine they are in. + + + +* Auto Configure - Major changes to add more default prestige ranks, and the ability to go back and add more ranks after your server is up and running without harming anything. + - Added support to reset all rank cost multiplier and rank costs to apply to all ranks on a ladder. + + +* XPrison Enchantments - Added some basic support for using the XPrison enchantments. There are some limitations, and not all enchantments will work perfectly. + + +* Placeholders - + - Disabled all placeholders in disabled worlds. + - New placeholder attribute to pass a player name to force a non-player placeholder request to use the specified player. This is useful for some scripting languages and other plugins. + + + +* Auto Manager - + - New fortune type: percentGradient. An alternative fortune calculation that is designed to be more linear distribution, based upon the tool's fortune. + - Able to use TokenEnchant's fortune level. + + +* BlockConverters - Starting to use some minor features. The first being Event Triggers where a given block can force prison to trigger another plugin and allow that plugin to handle all processing for that block. Example is using a lucky block. + + + +* **Prison compatibility: Added support for block metadata customModelData.** + - This is only compatible with spigot 1.14.x and higher. + - Supported in prison mine bombs so you can customize the bomb's texture + + + +* Prison performance improvements: + - More options to fine tune control of the player cache, mine reset control, economy cache, etc... + - Need to produce a document that covers performance optimization for prison + - Some default settings have been changed to encourage better performance out-of-the-box + + + + + + + +# 3.3.0-alpha.16 2023-11-18 + + +* **Fixed an issue with ranks being disabled. It now skips over this processing when ranks are disabled.** + + + +* **Modules: Changed the way some of the module management is used to help prevent errors when a module is disabled.** +Suppress disabled modules from the placeholder list... only Ranks and Mines, which covers all of the placeholders. + + + +* **Sellall: Standardize how sellall is being checked to see if it's enabled.** +There are still a few ways it can be improved, but this is a step in the right direction. +There was a problem with the older way things were being handled that was causing an NPE with the SpigotPlayer, which was brought to my attention by DinoFengz, but I noticed there were other problems that needed to also be addressed. + + +* **Economy support for CoinsEngine: support has been initially added**, but it is unsure if it is working correctly. This request originated from pingu and they said it's not working, but has not provided any more information. Unsure how it's not working, or if they cannot use it the way they originally envisioned because sellall cannot support different currencies for different items within sellall. +Because of the lack of an API jar to be used, a new sub-project 'prison-misc' was created to be able to generate a pseudo-shell api for the CoinsEngine plugin. This pseduo api jar is used strictly to allow the successful compiling of the prison's economy hooks for CoinsEngine. +NOTE: I have not heard back from pingu to know if this is working. If you try to use this plugin and you have issues, please contact me on our discord support server. + + +* **Block Converters: Change the usage to Player instead of RankPlayer since if ranks are disabled then RankPlayer could not exist.** + + +** 3.3.0-alpha.15h 2023-11-05** + + +* **Player Cache: Put some of the player cache numbers in to the config.yml file so they can be fine tuned if desired.** +See the changes to config.yml for information to what the new setting controls. + + +* **GUI: Add support for changing the gui item names for Ranks and Mines. Ranks can now set their material type too.** + + +* **Updated nbt-api and fixed a new issue that was introduced with mc 1.20.2.** + + +* **Placeholder attribute time: add the time attribute to 4 more placeholders.** + + +* **Auto Sell: Bug fix for full inventory when auto sell is toggled off, which was incorrectly selling the player's inventory.** + + +* **Prison Debug: Added support to target some debug logging to a specific player.** +When enabled, it will ignore all other players. Not all debug messages have been hooked up. More can be added upon request. +When debug mode is disabled, it will remove the debug player name. + + +* **Placeholders: Added support for a new placeholder attribute to better format time based placeholders.** + + +* **Placeholders: Added the ability to provide a shorted output of the command `/prison placeholders test` so it only shows the command header and the results.** +Use the '-s' flag as in: '/prison placeholders test -s' + + +* **Placeholders: bug fix: If using the placeholder attribute for an off line player, it would cause an error when checking if the player was in a disabled world.** + + +* **SellAll messages: Cleaned up some of the US EN messages related to the sellall command.** + + +* **Bug: sellall auto sell enabled messages reversed.** +The command to enable and disable the auto sell feature was reversed, so when turning off, it would report that it was just turned on. And on when it was turned off. + + +**v3.3.0-alpha.15g 2023-10-03** + + +* **Player Economy Cache Delay: Add the ability to change the player economy cache delay. Default value is 3 seconds, or 60 ticks.** + + +* **Prison version: Improve the content of the auto features details.** + + +* **Placeholders: Added the ability to specify a player name in all placeholder attributes.** +This can allow the use of placeholders that are player centric in plugins that cannot support player based placeholder requests. + + +* **Autosell: Setup the SpigotPlayer object to support functions to identify if the player has autosell enabled. This is used in a couple of places to eliminate redundancy.** +Fixes a problem with the block break event not also checking to see if the player has toggled their autosell status for the forced sell after the event is processed, and also the delayed sell. + + +* **Cleanup the '/ranks list' to add mines and better format the name, tag, and cost.** +Also removed rankId which is not important anymore. + + +* **Auto features: change a few of the new line breaks so there are fewer.** + + +* **Changed the default color code from `&9` (dark blue) to `&b` (light blue) for debug logging since the dark blue could be difficult to see on some consoles. + + +**v3.3.0-alpha.15f 2023-09-24** + + +* **TopNPlayer: Task could not startup if ranks are enabled but there are no default ranks.** +Log a message in the console that the task cannot start because ranks are enabled and there are no ranks. +Request that Ranks module is disabled, or add default ranks and then restart the server. + + +* **Prison Support: Added a more secure method and server (privatebin) for submitting server information under prison support submit commands.** +Can now control some of the settings that are used, including password, in the config.yml file. +May need to refresh config.ymml to see now settings. + + +* **MineBombs: validate all mine bombs upon server startup to validate the sound effects, visual effects, and shape based upon the version of spigot that they are running.** +This mostly is to clean up the default mine bombs where they have sound and visual effects for versions of spigot so something will happen. This removes the invalid ones for the version so there are less errors at run time. + + +* **MineBombs: Add support for customModelData for the item used for the bomb.** +This will only work on spigot version 1.14.x and higher. + + +* **Prison compatibility: Added support for block metadata customModelData.** +This is only compatible with spigot 1.14.x and higher. + + +* **Ranks Ladder resetRankCost: Added a new parameter to provide an exponent which is used as a Math.pow() function over the base rank cost calculations.** +This can help increase the rank costs for higher ranks. +Default value is 1.0 so it does not apply unless it is specifically changed. + + +* **Update the Double vs BigDecimal example. Increased from 25 to 35 iterations, and expanded all columns to adjust for the wider output.** + + +* **Block Converters: event triggers: More work. Got it working to the point that it's ready for production.** +The way it is right now, any block that is in an event trigger, will be excluded from all explosions. They will remain unbroken in the mine. +The players can then break them directly to trigger the events. Eventually I may allow processing within an explosion event, but right now it's not making sense to process 100+ triggers all at one time for huge explosions... the other plugin that's being "fired" may cause lag trying to process that many at one time. + + + +* **BlockConverters eventTriggers: Fixed the handling of event trigger blocks so they can be ignored within an explosion event. Now works.** +Still have to process the event trigger blocks in explosions for when they need to be triggered. + + +* **Sellall command: '/sellall set delay' - fixed the description which had a typo in the description.** + + +* **SpigotPlayer: fixed a problem where the object was expected to be comparable.** + + +* **BlockConverters eventTriggers: Add the support for explosion events to all of the explosion event handlers.** + + +* **BlockConverters EventTriggers: Setup the next phase of handling where blocks in explosions can be ignored.** + + +* **BlockConverters EventTriggers - setup the PrisonMinesBlockBreakEvent to allow an event to identify if the primary block must be forcefully removed**, which is only used right now with event triggers, and would remove the block when handling a MONITOR event, which normally does not remove any blocks. + + +* **BlockConverters EventTriggers: Setup more controls within the settings of a blockEvent.** +Setup the ability to control processing of drops: if disabled, it will treat the block event as a MONITOR. This allows the block to be counted correctly. +Setup the ability to ignore the block type within all explosions, so each block would have to be broken individually. +Setup the ability to remove the block without dropping anything since another plugin would have already processed the block, so nothing would remain to be done with it. + + +* **Mines block edit - Found a problem where if you are trying to edit a block and the name does not match, it was causing an error.** Now reports that the block name is invalid. + + +* **Block Converters - Event Triggers - Had issues with block names not matching, so using all lower case. When using an event trigger it now logs the debug info to the console.** +This will need more work, such as block removal and logging as if it were a MONITOR priority. +At this point, we are testing to confirm that the event is actually being triggered. So far it looks like it is working as intended. + + +* **Block Converters: Start to hook up block converters to auto features.** +Changed how block converters were structured to get them to work with the prison environment. +Hooked up the Block Converter Event Trigger to the bukkit BlockBreakEvent. Explosions are not yet covered, will add support for them if this appears to work. + + +* **Update docs and some command descriptions to make them a little more clearer as to what they do.** + + +* **sellall multipliers list: Added 2 options to control the number of columns displayed with 'cols=7' and also only show multipliers for a single ladder if that ladder name is provided in the options.** + + +* **sellall multiplier list: Now applies a sort order to the ranks, grouping by ladders.** It groups by ladders, and then lists the ranks in rank order, within each ladder. + + +* **sellall multiplier addLadder: added more comments to the command's help, and added defaults to the parameters.** + + +* **SellAll multipliers: Increased the number of columns for the listing to 8 columns instead of 5.** May need to expand it even more so if there are thousands of ranks, it can be better managed. +New command: `/sellall multiplier deleteLadder` deletes all multipliers for that ladder. +New command: `/sellall multiplier addLadder` adds multipliers for all ranks on the ladder. + + +* **Ranks Auto Configure: Fixed message format when options are not valid so it's better understood what's wrong with the command.** +The parameter names are case sensitive, but added a fallback mapping to lowercase so there is a higher chance of matching the correct commands. +Had to move the location of the 'prestigeMulti=' parameter to be evaluated before 'multi=' parameter since it was taking over the `prestigeMulti=` parameter. + + +* **Update the rank's getPosition() java docs to better clarify what it is.** + + +* **Ladders: Added a new command to reset all rank costs for a given ladder: '/ranks ladder resetRankCosts help'** +This will allow a simple and easy change to all rank costs within a given ladder even if there are many ranks, such as the presetiges ladder which could have thousands of ranks. +These calculations are similar to how the `/ranks autoConfigure` will set them up. + + +* **Prison logging: When line breaks are applied in log messages, it will no long include the prison template prefix with the message to reduce the clutter and make it easier to read multi-lined content.** +The line break placeholder is '{br}', similar to the html element BR. + + + +**v3.3.0-alpha.15e 2023-09-03** + +* **Prison messages: Expanded the use of prison message line breaks, `{br}` in both console messages and sending messages to player.** +Auto Features: Added line breaks to the existing block break debug info since it's very long and difficult to read. + + +* **Mine wand debug info: Slightly alter the printing of the details to make it easier to read.** + + + +* **AutoFeatures and prison version: I have no idea why I added an auto features reload when doing prison version. Removed.** +Best guess at this moment is that it was to test something. + + +* **Prison GUI: When disabled through the config.yml 'prison-gui-enabled: false' there were still some commands that were being registered with the '/gui' root.** +As a result, prison was taking over the use of the command '/gui' that was trying to be used by other plugins. +This fix tries to isolate the GUI commands from backpacks, prestiges, and sellall, to make sure they cannot be registered if GUI is disabled. +Had to create new classes to allow the isolation when registering the commands. + + +* **AutoManager: percent gradient fortune: Changed the calculations to use doubles instead of integers.** + + +* **Slime-fun: Moved a lot of the settings for it to the config.yml file instead of hard coding them.** +Now the messages can be turned off, and the boosters can now be added to, and changed. + + +* **Sellall: Fixed a bug with spigot 1.8.8 where bricks were not able to be sold correctly.** +The issue is with XBlock not correctly mapping brick and bricks to the correct bukkit 1.8 materials. It may be close, or accurate, but when converting to a bukkit item stack, it fails to map back to the same objects. +Sellall was not using the prison compatibility classes, and those classes for 1.8 had to be updated too. + + +* **AutoFeatures: New option to use TokenEnchant to get the enchantment level through their API instead of using the bukkit functions to get the fortune.** + + +* **AutoFeatures: Added a debug statement when player autosell has been toggled off by the player, since it may look as if autosell is not working correctly.** +Wrapped the notice in a WARNING color code so it stands out in the console with it being red. + + +* **AutoFeatures: Updated the gradient fortune to fix a problem with not setting the bonus block counts correctly.** + + +* **AutoManager: Added a new fortune type: percentGradient.** +This fortune calculation is an alternative to the extendedBukkit and altFortune calculations. +This fortune calculation applies a linear distribution based upon the player's tool's fortune level versus the maxfortuneLevel and the maxBonusBlocks. + + +* **Added a `/mines top` command, alias `/mtop`, which will tp a player to the spawn location of the current mine they are in. ** +If they are not in a mine, then it will tp them to a mine tied to their current default rank. + + +**v3.3.0-alpha.15d 2023-08-16** + + +* **Mine reset time: Found a conflict with the setting '*disable*' being ignored.** +It's been fixed. + + +* **BlockBreak sync task: Found a possible cause of jitters, or visual appearance of lag.** +Basically, need to check the block to ensure it's not already AIR before setting it to AIR. This could happen if there is a heavy load on the server from other plugins, or from bukkit itself, and bukkit naturally breaks the block before prison's sync task can get to it. +Prison submits the sync task to run "next" in the future, but if there are other tasks trying to run, and if they cause a longer delay, then it can appear to be laggy. + + +* **AutoFeatures: Expand the number of features being reported to bstats.** +Removed a duplicate comment in the autoFeatures config file. + + +* **AutoFeatures: Add comment on autosell by perms so it's clear what setting are needed.** +Also added a setting of 'false', in addition to 'disable', which disables the permission based autosell. + + +* **AutoFeatures XPrison event listener: Fixed a bug that was ignoring the first block in the exploded block list.** + + +* **AutoFeatures: Added the ability to force a delayed inventory sellall at the end of handling a bukkit BlockBreakEvent. This is in addition to the other instant sellall at the end of the bukkit BlockBreakEvent.** +This has the ability to set a delay in ticks before it is fired. +If a task was submitted for a player, then future tasks cannot be submitted for that player until the submitted sellall task was finished running. +This was added to help cover situations where third party plugins are trying to add additional bonus drops to the players, but after prison is done handling the events. + + +* **AutoFeatures: Added the ability to force an inventory sellall at the end of handling a bukkit BlockBreakEvent.** +This was added to help cover situations where third party plugins are trying to add additional bonus drops to the players. + + +* **auto features: setup a sellall function on PrisonMinesBlockBreakEvent so it can be easier to utilize from other functions.** + + +* **AutoFeatures SellAll: Added the ability to disable the "nothing to sell" message without effecting the other settings.** + + +* **auto features: Add the calculated autosell to the dropExtra function to force autosell if it should happen to have extra drops left over (it never should).** + + +* **Auto Features: If autosell is enabled and there are any leftover blocks that was not sold, it will now generate an error message and if prison debug mode is turned off, then it will force the logging of the transaction.** +This forcing the logging can be turned off in the auto features configs. +Expanded the logging to change the color on some of the more important warnings and failures so they stand out. +Also reworked some of the log details to eliminate redundancy and clarify what's being logged. + + +* **AutoFeatures: Added support for XPrison's enchantments... forgot to add the API jar which is used to just compile prison (not used on servers).** + + +* **Prison Placeholders: Added support to disable placeholders in disabled worlds.** +This feature is not enabled by default. +Any disabled world in the prisonCommandHandler configs within config.yml, could also shutdown the prison placeholders in that world if enabled. +The placeholder text will be replaced with just an empty string. + + +* **Prestiges: Bug fix. If no prestige rank, then prevent a NPE on a simple check.** +Totally thought this was fixed a while ago? + + +* **AutoFeatures BlockInspector: Fixed a bug with not negating a condition... was causing some problems since it was misreporting the results.** + + +* **AutoFeatures: Add support for the XPrison enchantments.** +Please be aware that event priorities must be adjusted. You can change prison's event priorities, but XPrison is hard coded to NORMAL So to get this work, you may have to adjust prison's priorities so it is after XPrison's. +We cannot support XPrison especially if their event priorities become a problem, or causes a problem. + + +**v3.3.0-alpha.15c 2023-07-30** + + +* **RevEnchants: added additional logging and details if there is a failure trying to hook into the RevEnchant's events.** +Trying to see if there is additional causedBy information. + + +* **ranks autoConfigure: Major enhancements to add more prestige ranks.** +Added a lot more informatio to the command's help: `/ranks autoConfigure help`. +More options have been added: prestiges prestiges=x prestigesCost=x prestigesMult=x. +Now able to add more prestige ranks without impacting ranks or mines. +Example to add up to 50 new prestige ranks: `/ranks autoConfigure force presetiges prestiges=50` + + +* **Sellall: Rearrange the sellall commands so they are better organized and updated the help text so its also meaningful.** + + +* **sellall & autosell: auto sell was not working correctly within auto manager.** +Also fixed the user toggle on auto sell so players can turn off autosell when they need to. + + +* **Sellall: clean up some of the help for a few sellall features and expand on the details. ** + + +**v3.3.0-alpha.15b 2023-07-28** + + +* **Prevent a NPE if the target block is not found within the mine's settings.** + + +* **Mine Bombs: Found an issue with the bomb settings for allowedMines and preventMines, and fixed it.** +There is a global setting in config.yml under the settings: `prison-mines.mine-bombs.prevent-usage-in-mines` to disable all mine bombs from working in those mines. The bombs can then be individually added by setting adding mine names to the bomb configs settings for `allowedMines` and `preventedMines`. If a mine is included on a bomb's allowedMines setting, it will override any global setting. + + +* **Fixed an issue with BRICKS being mismatched to BRICK. This is an XSeries bug.** + + +* **TopN: TopN was not being disabled correctly for when ranks were disabled.** +This now properly checks the PrisonRanks to see if the ranks module is active or not. The prior code was not being as detailed. + + +* **Prison support: Added more color related test. Changed the color schema name from 'madog' to 'prison'.** + + +* **Mines set tracer: Update the command to add options for 'clear' the whole mine, and 'corners' where it clears the whole mine but puts the tracer only in the corners.** +The default option of 'outline' is the default value, and if 'clear' or 'corners' is not set, then it will default to the standard outline, or tracer. + + +* **Enable all Ranks to be used with the sellall rank multiplier.** +It used to be limited to just prestige ranks, but there has been requests to expand to all ranks. + + +* **Fixed a color code conflict in the ranks list when displaying the default rank.** +It wasn't wrong, but it was showing incorrectly. Added a reset `&r` and that fixed it. Almost like too much nesting got in the way. + + +* **Prison Support: Support HTML file: Added a color test to prison, color matched on the console's colors to provide an accurate reproduction and match with the console.** +Added the ability to support themes: console is the primary, with Madog being an alternative. Can have others themes too. +Fixed a few layout issues. Added the ladder listing, which did not exist before. Setup the placeholders for the hyperlinks... they will be added next along with the auto generation of a table of contents. + + +* **Prison Support: More enhancements to the html save file.** +Instead of calling the four `/prison support submit` commands, they are all now generated from within the same function. This will allow the collection of all hyperlinks to generate a tabl of contents. +Improvements to the layout of some of the items in report. + + +* **Prison Support: Enabling the initial save file to an HTML file.** +Color codes are working great, but needs some tweaking. +The framework for hyperlinks are inserted in most locations... they are just double pipes surrounding 2 or 3 words. I will generate a series of classes that will auto generate hyperlinks and table of contents based upon these encodings. + + +* **Prison Support: More setup of the new SupportHyperLinkComponent, but mostly the java docs which explains it pretty well.** + + +* **Prison Support: Setup the Platform with the function to get the related Rank name or Ladder name, based upon the save file's name.** +This is used to reverse engineer which rank or ladder is tied to a give file, without having to read the file. + + +* **Prison Support: Start to setup an alternative support file target, of an html file.** +This file will also convert minecraft color codes to html colors. + + +* **PrisonPasteChat: change the exception to just Exception so it can capture all errors.** +The server has been down for the last two days and so other errors need to be caught. + + +* **If at last rank, show a message to tell the player that.** + + +* **Added a few more items to the default list of items in sellall.** + + +* **Added new feature to prevent mine bombs from being used in mines.** +A specific mine bomb can have a list of included mines, which overrides any exclusions. The mine bombs can be excluded from specific mines too. +There is also a global disallowed mine list that will apply to all mine bombs, its in the config.yml file with the setting name of: + prison-mines.mine-bombs.prevent-usage-in-mines +There is a global setting in config.yml under the settings: `prison-mines.mine-bombs.prevent-usage-in-mines` to disable all mine bombs from working in those mines. The bombs can then be individually added by setting adding mine names to the bomb configs settings for `allowedMines` and `preventedMines`. If a mine is included on a bomb's allowedMines setting, it will override any global setting. + + +* **The Platform function getConfigStringArray should be a List of Strings for the return value, so updated the result type to reflect the correct setting.** + + +* **Bug fix: If a sellall transaction is null, then it now returns a zero since nothing was sold.** + + +* **More adjustments to the PrisonDebugBlockInspector for readability.** + + +* **Auto features not being fully disabled when turned off.** +There was an issue with `/prison reload autoFeatures` enabling itself when it should have been off. + + + +** v3.3.0-alpha.15a 2023-07-16** + + + + +* **Enhance Prison's debug block inspector to fix an issue with running it multiple times for one test.** +Reformatted the layout so each plugin is now using only one line instead of two, and added the duration of runtime in ms. + + +* **SellAllData: The transaction log: Enhanced the itemsSoldReport by combining (compressing) entries for the same PrisonBlock type.** +This will make it easier to review since there will be only one entry per PrisonBlockType. + + +* **Auto Features AutoSell fix: There were situations where mine bombs that are set with the setting autosell was not being sold.** +Found a conflict with the logic of enabling autosell within the auto pickup code. There are four ways autsell could be enabled, and a couple were incorrectly mixed with their logic. +Debug mode is now showing drop counts before and after adjustments from the fortune calculations. + + +* **Prison tokens: expanded the error messages for playing not being found to the set and remove functions for the admin token commands.** + + +* **Prison Tokens: bug fix: Ran in to NPE when an invalid player name is used.** +The message text needs to be stored in the lang files. + + +* **Fixed a bug with using the wrong player object within auto feature's autosell.** + + +* **Update the prison API to add direct support for payPlayer function (various options).** + + +* **Prison Multi-Language Locale Manager: Updated all language files to include information about the new `*none*` keyword.** +This keyword is case insensitive and will return an empty string for that message component if it's part of a compound message. If the message is supposed to be sent to a player, it will be bypassed and nothing will be sent. + + +* **Prison Multi-Language Locale Manager: Possibly fixed a few issues with setting messages to "blanks". If the text of a message is removed, and set to an empty string, it should not be used.** +There was a situation where a zn_TW language file was set to an empty string and it was falling back to the en_US version. +I found that there was a bug with a sendMessage() function to a player that was not bypassing the message like the other functions were doing. +Also in the code where it was calculating the Locale variations, it was not accepting a blank as the final input. This was fixed. +Also, to be clear, or more specific, I added a new keyword `*none*` to serve the same purpose. So either an empty string can be used, or that new `*none*` key word. + + +* **More work on getting the new world guard sub-projects hooked up and functional in the build with gradle.** + + +* **Update the PrisonSpigotAPI to include a lot of new api endpoints for accessing sellall related functions.** + + +* **Sellall: Expanded the functionality of the SellAllData obejects to indicate if the items were sold.** + + +* **New sellall features: 'sellall valueof' calculates the value of everything in the player's inventory that can be sold. '/sellall valueofHand' calculates what is held in the player's hand.** + + +* **Major rewrites to sellall to utilize more of Prison's internal classes and to get away from XMaterial since it cannot handle custom blocks.** +A lot of sellall code has been eliminated, but no loss in functionality. Actually new functions and enhancements have been added. +Eliminated the two step process of selling... where it first calculated the values, then after the fact, would try to remove the items with no "validation" that the items removed were the items that calculated the sales amount. +Sellall commands: moved the '/sellall trigger add' and '/sellall trigger remove' to under the '/sell set' section since they were hidden because '/sellall trigger' was a command and many did not realize they have to use the 'help' keyword to show the others. + + +* **Updated Prison's PlayerInventory to include 'contents' and 'extraContents' to match the bukkit PlayerInventory object.** +Within the SpigotPlayerInventory class, overrode the behavior of removeItem to ensure that obscure inventory locations are being removed, since there was a bug where you can get all inventory items, then remove them, and they would not remove all occurrences of the items stacks that were initially returned, such as when someone is wearing an item as a hat, or holding something in one of their hands. + + +* **Allow additional parameters to be passed on the gradlew.bat command; needed for additional debugging and etc...** + + +* **Add new salePrice and purchasePrice to the prison Block.** + + +* **Sellall : remove the disabled worlds setting in the configs since it is obsolete and never used.** +The correct way to disable prison in specific worlds is by using the config.yml settings for prisonCommandHandler.exclude-worlds. + + +* **Bug fix... this is a continuation of a prior issue of prison commands not being mapped to their assigned command name by bukkit when prison's command handler registers them.** +This was an issue with another plugin that registered `/gui` before prison was able to, so then all of prison's gui commands were mapped to `/prison:gui`. So where this was an issue was with `/prestige` trying to run the gui presetige confirmation which was trying to kick off a GuiPlus command as a result of this improper mis-match. +Tested to confirm it is now functional. Changed all occurrences that I could find that also needed to be mapped. + + +* **Start to setup support for WorldEdit and WorldGuard.** + + +* **Setup a way to pull a config's hash keys.** +These would be used to dynamically get all settings within a hash. + + +* **Fixed an issue with prison commands being remapped, but other commands within prison were not using them.** +This tries to find the remapped command for all commands by updating the SpigotCommandSender.dispatchCommand(). + + +* **Fixed an issue where the setting isAutoFeaturesEnabled was not being applied to the permissions which resulted in the perms always being enabled when OPd.** + + +* **2023-07-07 v3.3.0-alpha.15 Released** + + + diff --git a/docs/prison_changelogs.md b/docs/prison_changelogs.md index 2a221dcc9..f0badc17a 100644 --- a/docs/prison_changelogs.md +++ b/docs/prison_changelogs.md @@ -9,8 +9,9 @@ These are internal notes that may initially record ideas and issues. They may n reflect the final actions taken as expressed in the change logs below, so these may be insightful in to some of the evolutionary processes. -* [Known Issues - Open](knownissues_v3.2.x.md) -* [Known Issues - Resolved](knownissues_v3.2.x_resolved.md) +* [Known Issues - v3.3.x Open](knownissues_v3.3.x.md) +* [Known Issues - v3.3.x Resolved](knownissues_v3.3.x_resolved.md) +* [Known Issues - v3.2.x](knownissues_v3.2.x.md) ## Change logs @@ -21,6 +22,7 @@ These build logs represent the work that has been going on within prison. - Future updates will be under the v3.3.x release + - [v3.3.3-alpha.16 - 2023-11-18](prison_changelog_v3.3.0-alpha.16.md)   - [v3.3.3-alpha.15 - 2023-07-07](prison_changelog_v3.3.0-alpha.15.md)   - [v3.3.3-alpha.14 - 2023-01-23](prison_changelog_v3.3.0-alpha.14.md)   diff --git a/docs/prison_docs_000_toc.md b/docs/prison_docs_000_toc.md index 2221917bd..66e1cd54a 100644 --- a/docs/prison_docs_000_toc.md +++ b/docs/prison_docs_000_toc.md @@ -2,15 +2,14 @@
-*Documented updated: 2022-12-30* +*Documented updated: 2023-11-18* ## Project Related * **[Prison README](prison_readme.md)** High level information, plus how to use with gradle builds. * **[Prison License](prison_license.md)** GNU General Public License * **[Prison Change logs](prison_changelogs.md)** Detailed changes to prison. -* **[Prison Known Issues - Open](knownissues_v3.3.x.md)** Known Issues and To Do's. -* **[Prison Known Issues - Resolved](knownissues_v3.3.x_resolved.md)** Resolved Known Issues and To Do's. + * **[Prison Discord Server](https://discord.gg/DCJ3j6r)** Get help here.